문제

혹시 사용해보신 분 계신가요? 브릿지 패턴 실제 응용 프로그램에서는?그렇다면 어떻게 사용하셨나요?저인가요, 아니면 약간의 종속성 주입이 포함된 어댑터 패턴인가요?정말 자신만의 패턴을 가질 자격이 있나요?

도움이 되었습니까?

해결책

브리지 패턴의 전형적인 예는 UI 환경에서 모양의 정의에 사용됩니다 ( 브리지 패턴 위키 백과 진입). 브리지 패턴은 a 합성물주형 그리고 전략 패턴.

교량 패턴에서 어댑터 패턴의 일부 측면은 일반적인보기입니다. 그러나 인용합니다 이 기사:

첫눈에, 브리지 패턴은 클래스가 한 종류의 인터페이스를 다른 인터페이스로 변환하는 데 사용된다는 점에서 어댑터 패턴과 비슷해 보입니다. 그러나 어댑터 패턴의 의도는 하나 이상의 클래스 인터페이스를 특정 클래스의 인터페이스와 동일하게 보이게하는 것입니다. 브리지 패턴은 클래스의 인터페이스를 구현과 분리하여 클라이언트 코드를 변경하지 않고도 구현을 변경하거나 교체 할 수 있도록 설계되었습니다.

다른 팁

조합이 있습니다 Federico 's 그리고 답변.

언제:

                   ----Shape---
                  /            \
         Rectangle              Circle
        /         \            /      \
BlueRectangle  RedRectangle BlueCircle RedCircle

refactor to :

          ----Shape---                        Color
         /            \                       /   \
Rectangle(Color)   Circle(Color)           Blue   Red

브리지 패턴은 "상속보다 구성을 선호하는"오래된 조언의 적용입니다. 서로 직교하는 방식으로 다른 시간을 서브 클래스해야 할 때 유용 해집니다. 색상 모양의 계층 구조를 구현해야한다고 가정 해 봅시다. 직사각형과 원으로 서브 클래스 모양을하지 않은 다음 redrectangle, bluerectangle 및 greenrectangle을 사용하여 서브 클래스 사각형과 원에 대해서도 동일합니까? 당신은 각 모양을 말하는 것을 선호합니다 가지다 색상과 색상의 계층 구조를 구현하기 위해 브리지 패턴입니다. 글쎄, 나는 "색상의 계층 구조"를 구현하지는 않지만 아이디어를 얻는다 ...

언제:

        A
     /     \
    Aa      Ab
   / \     /  \
 Aa1 Aa2  Ab1 Ab2

refactor to :

     A         N
  /     \     / \
Aa(N) Ab(N)  1   2

어댑터와 브리지는 확실히 관련이 있으며 구별은 미묘합니다. 이러한 패턴 중 하나를 사용하고 있다고 생각하는 일부 사람들은 실제로 다른 패턴을 사용하고있을 것입니다.

내가 본 설명은 어댑터가 호환되지 않는 클래스의 인터페이스를 통합하려고 할 때 사용된다는 것입니다. 이미 존재합니다. 어댑터는 고려 될 수있는 구현에 대한 일종의 번역기 역할을합니다. 유산.

Bridge 패턴은 Greenfield 일 가능성이 높은 코드에 사용됩니다. 다리가 필요한 구현에 대한 추상 인터페이스를 제공하기 위해 브리지를 설계하고 있지만 해당 구현 클래스의 인터페이스도 정의합니다.

장치 드라이버는 종종 브리지의 예제이지만 장치 공급 업체의 인터페이스 사양을 정의하는 경우 브리지라고 말하지만 기존 장치 드라이버를 가져 와서 래퍼 클래스를 만드는 경우 어댑터입니다. 통합 인터페이스를 제공합니다.

따라서 코드 측면에서는 두 패턴이 매우 유사합니다. 비즈니스 측면에서는 다릅니다.

또한보십시오 http://c2.com/cgi/wiki?bridgepattern

내 경험에 따르면 Bridge는 자주 반복되는 패턴입니다. 도메인에는 두 개의 직교 차원이 있습니다..예:모양 및 그리기 방법, 동작 및 플랫폼, 파일 형식 및 직렬 변환기 등.

그리고 조언:항상 디자인 패턴을 생각하세요 개념적인 관점에서, 구현 관점이 아닙니다.올바른 관점에서 보면 Bridge는 다른 문제를 해결하고 구성은 그 자체 때문이 아니라 직교 문제를 별도로 처리할 수 있기 때문에 상속보다 우수하기 때문에 Adapter와 혼동할 수 없습니다.

의도 다리 그리고 어댑터 다르고 두 패턴이 별도로 필요합니다.

브리지 패턴 :

  1. 구조적 패턴입니다
  2. 추상화 및 구현은 컴파일 시간에 구속되지 않습니다
  3. 추상화 및 구현 - 둘 다 클라이언트의 영향없이 다를 수 있습니다.
  4. 상속에 대한 구성을 사용합니다.

다음과 같은 경우 브리지 패턴을 사용하십시오.

  1. 구현의 런타임 바인딩을 원합니다.
  2. 결합 된 인터페이스 및 수많은 구현으로 인한 클래스가 확산됩니다.
  3. 여러 객체간에 구현을 공유하고 싶습니다.
  4. 직교 클래스 계층을 매핑해야합니다.

@ John Sonmez는 클래스 계층 구조를 줄이는 데있어 브리지 패턴의 효과를 명확하게 보여줍니다.

코드 예제와 함께 브리지 패턴에 대한 더 나은 통찰력을 얻으려면 아래 문서 링크를 참조 할 수 있습니다.

어댑터 패턴:

  1. 그것 관련없는 두 개의 인터페이스가 함께 작동 할 수 있습니다 다른 물체를 통해 동일한 역할을 수행 할 수 있습니다.
  2. 원래 인터페이스를 수정합니다.

주요 차이점 :

  1. 어댑터 그들이 설계된 후에 일을 작동시킵니다. 다리 그들이 있기 전에 일을하게합니다.
  2. 다리 틀리기 위해 선불로 설계되었습니다 추상화와 구현은 독립적으로 다릅니다. 어댑터 관련없는 수업이 함께 작동하도록 개조됩니다.
  3. 의도 : 어댑터 관련없는 두 개의 인터페이스가 함께 작동 할 수 있습니다. 다리 추상화와 구현이 독립적으로 다를 수 있습니다.

UML 다이어그램 및 작업 코드와 관련된 SE 질문 :

브리지 패턴과 어댑터 패턴의 차이

유용한 기사 :

사워 메이킹 다리 패턴 기사

사워 메이킹 어댑터 패턴 기사

저널 데브 브리지 패턴 기사

편집하다:

Bridge Pattern Real World 예제 (Meta.stackoverflow.com 제안,이 게시물에 문서화 사이트 예제 문서가 SUNET으로 진행하기 때문에)

브리지 패턴은 구현에서 추상화를 해체하여 둘 다 독립적으로 다를 수 있습니다. 상속이 아닌 구성으로 달성되었습니다.

Wikipedia의 Bridge Pattern Uml :

Bridge pattern UML from Wikipedia

이 패턴에는 네 가지 구성 요소가 있습니다.

Abstraction: 인터페이스를 정의합니다

RefinedAbstraction: 추상화를 구현합니다.

Implementor: 구현을위한 인터페이스를 정의합니다

ConcreteImplementor: 구현 자 인터페이스를 구현합니다.

The crux of Bridge pattern : 구성을 사용한 두 개의 직교 클래스 계층 (및 상속이 없음). 추상화 계층 구조 및 구현 계층 구조는 독립적으로 다를 수 있습니다. 구현은 결코 추상화를 참조하지 않습니다. 추상화에는 구성을 통해 구현 인터페이스가 포함됩니다 (구성을 통해). 이 구성은 하나의 상속 계층 구조 수준을 줄입니다.

실제 단어 사용 사례 :

다른 차량에 수동 및 자동 기어 시스템의 버전을 모두 가질 수 있도록합니다.

예제 코드 :

/* Implementor interface*/
interface Gear{
    void handleGear();
}

/* Concrete Implementor - 1 */
class ManualGear implements Gear{
    public void handleGear(){
        System.out.println("Manual gear");
    }
}
/* Concrete Implementor - 2 */
class AutoGear implements Gear{
    public void handleGear(){
        System.out.println("Auto gear");
    }
}
/* Abstraction (abstract class) */
abstract class Vehicle {
    Gear gear;
    public Vehicle(Gear gear){
        this.gear = gear;
    }
    abstract void addGear();
}
/* RefinedAbstraction - 1*/
class Car extends Vehicle{
    public Car(Gear gear){
        super(gear);
        // initialize various other Car components to make the car
    }
    public void addGear(){
        System.out.print("Car handles ");
        gear.handleGear();
    }
}
/* RefinedAbstraction - 2 */
class Truck extends Vehicle{
    public Truck(Gear gear){
        super(gear);
        // initialize various other Truck components to make the car
    }
    public void addGear(){
        System.out.print("Truck handles " );
        gear.handleGear();
    }
}
/* Client program */
public class BridgeDemo {    
    public static void main(String args[]){
        Gear gear = new ManualGear();
        Vehicle vehicle = new Car(gear);
        vehicle.addGear();

        gear = new AutoGear();
        vehicle = new Car(gear);
        vehicle.addGear();

        gear = new ManualGear();
        vehicle = new Truck(gear);
        vehicle.addGear();

        gear = new AutoGear();
        vehicle = new Truck(gear);
        vehicle.addGear();
    }
}

산출:

Car handles Manual gear
Car handles Auto gear
Truck handles Manual gear
Truck handles Auto gear

설명:

  1. Vehicle 추상화입니다.
  2. Car 그리고 Truck 두 가지 구체적인 구현입니다 Vehicle.
  3. Vehicle 추상 방법을 정의합니다. addGear().
  4. Gear 구현 자 인터페이스입니다
  5. ManualGear 그리고 AutoGear 두 가지 구현입니다 Gear
  6. Vehicle 포함 implementor 인터페이스를 구현하는 대신 인터페이스. Compositon 구현 자 인터페이스의이 패턴은 다음과 같습니다. 추상화와 구현이 독립적으로 다를 수 있습니다.
  7. Car 그리고 Truck 추상화에 대한 구현 (재정의 된 추상화) 정의 : addGear() : 포함되어 있습니다 Gear - 어느 하나 Manual 또는 Auto

브리지 패턴의 사용 사례:

  1. 추출 그리고 구현 서로 독립적 인 변화가있을 수 있으며 컴파일 시간에 묶이지 않습니다.
  2. 지도 직교 계층 - 하나 추출 그리고 하나를 위해 구현.

나는 직장에서 브리지 패턴을 사용했습니다. 나는 C ++로 프로그램되어 종종 PIMPL IDIOM (구현에 대한 포인터)이라고합니다. 다음과 같이 보입니다.

class A
{
public: 
  void foo()
  {
    pImpl->foo();
  }
private:
  Aimpl *pImpl;
};

class Aimpl
{
public:
  void foo();
  void bar();
};  

이 예에서 class A 인터페이스를 포함합니다 class Aimpl 구현을 포함합니다.

이 패턴에 대한 한 가지 사용은 구현 클래스의 공개 구성원 만 노출시키는 것입니다. 예제에서만 Aimpl::foo() 공개 인터페이스를 통해 호출 할 수 있습니다 A, 하지만 Aimpl::bar()

또 다른 장점은 정의 할 수 있다는 것입니다 Aimpl 사용자가 포함 할 필요가없는 별도의 헤더 파일에서 A. 당신이해야 할 일은 다음과 같은 선언을 사용하는 것입니다. Aimpl ~ 전에 A 정의되고 모든 멤버 기능의 정의를 참조합니다. pImpl .CPP 파일로. 이것은 당신에게 보관할 수있는 능력을 제공합니다 Aimpl 헤더 비공개로 컴파일 시간을 줄입니다.

코드에 모양 예제를 넣으려면 :

#include<iostream>
#include<string>
#include<cstdlib>

using namespace std;

class IColor
{
public:
    virtual string Color() = 0;
};

class RedColor: public IColor
{
public:
    string Color()
    {
        return "of Red Color";
    }
};

class BlueColor: public IColor
{
public:
    string Color()
    {
        return "of Blue Color";
    }
};


class IShape
{
public:
virtual string Draw() = 0;
};

class Circle: public IShape
{
        IColor* impl;
    public:
        Circle(IColor *obj):impl(obj){}
        string Draw()
        {
            return "Drawn a Circle "+ impl->Color();
        }
};

class Square: public IShape
{
        IColor* impl;
    public:
        Square(IColor *obj):impl(obj){}
        string Draw()
        {
        return "Drawn a Square "+ impl->Color();;
        }
};

int main()
{
IColor* red = new RedColor();
IColor* blue = new BlueColor();

IShape* sq = new Square(red);
IShape* cr = new Circle(blue);

cout<<"\n"<<sq->Draw();
cout<<"\n"<<cr->Draw();

delete red;
delete blue;
return 1;
}

출력은 다음과 같습니다.

Drawn a Square of Red Color
Drawn a Circle of Blue Color

순열로 인한 서브 클래스의 폭발로 이어지지 않고 시스템에 새로운 색상과 모양을 추가 할 수있는 편리성을 주목하십시오.

저에게는 인터페이스를 교환 할 수있는 메커니즘으로 생각합니다. 실제 세계에는 하나 이상의 인터페이스를 사용할 수있는 클래스가있을 수 있습니다. Bridge는 교체 할 수 있습니다.

Bridge design pattern we can easily understand helping of service and dao layer.

Dao layer -> create common interface for dao layer ->
public interface Dao<T>{
void save(T t);
}
public class AccountDao<Account> implement Dao<Account>{
public void save(Account){
}
}
public LoginDao<Login> implement Dao<Login>{
public void save(Login){
}
}
Service Layer ->
1) interface
public interface BasicService<T>{
    void save(T t);
}
concrete  implementation of service -
Account service -
public class AccountService<Account> implement BasicService<Account>{
 private Dao<Account> accountDao;
 public AccountService(AccountDao dao){
   this.accountDao=dao;
   }
public void save(Account){
   accountDao.save(Account);
 }
}
login service- 
public class LoginService<Login> implement BasicService<Login>{
 private Dao<Login> loginDao;
 public AccountService(LoginDao dao){
   this.loginDao=dao;
   }
public void save(Login){
   loginDao.save(login);
 }
}

public class BridgePattenDemo{
public static void main(String[] str){
BasicService<Account> aService=new AccountService(new AccountDao<Account>());
Account ac=new Account();
aService.save(ac);
}
}
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top