브리지 패턴과 전략 패턴의 차이점은 무엇입니까?


114

나는 dofactory , wikipedia 및 많은 사이트 에서 많은 기사를 읽으려고 노력했습니다 . 브리지 패턴과 전략 패턴의 차이점에 대해 전혀 모릅니다.

둘 다 구현에서 추상화를 분리하고 런타임에 구현을 변경할 수 있음을 알고 있습니다.

하지만 어떤 상황에서 전략을 사용해야하는지, 어떤 상황에서 브리지를 사용해야하는지 여전히 잘 모르겠습니다.

답변:


66

의미론. 에서 위키 피 디아 :

전략 패턴의 UML 클래스 다이어그램은 Bridge 패턴의 다이어그램과 동일합니다. 그러나이 두 가지 디자인 패턴은 의도가 동일하지 않습니다. 전략 패턴은 행동을위한 것이지만 브리지 패턴은 구조를위한 것입니다.

컨텍스트와 전략 간의 결합은 추상화와 Bridge 패턴의 구현 간의 결합보다 더 엄격합니다.

내가 이해했듯이 외부 소스에서 제공 할 수있는 동작을 추상화 할 때 전략 패턴을 사용하고 (예 : config는 일부 플러그인 어셈블리를로드하도록 지정할 수 있음), 사용할 때 브리지 패턴을 사용하고 있습니다. 코드를 좀 더 깔끔하게 만들기 위해 동일한 구조를 사용합니다. 실제 코드는 매우 유사하게 보일 것입니다. 단지 약간 다른 이유로 패턴을 적용하는 것 입니다.


3
그래서 제가 전략 패턴을 사용하여 동작을 추상화하는 동시에 브리지 패턴 에서처럼 코드를 깔끔하게 보이도록 할 수 있다고 말할 수 있습니다. 또는 브리지 패턴을 사용하여 코드를 깔끔하게 만들고 전략 패턴에서와 같이 추상적 인 행동에 대해? 그리고 내가 옳을까요?
user20358 2012

1
이 둘의 차이점은 의도에만 있습니다. 그래서 우리는 둘 다 동일한 아이디어를 사용하고 동일한 유연성을 제공하기 때문에 두 패턴이 기능적으로 동일하다고 안전하게 말할 수 있다고 생각합니다.
엘즈 (Elz)

3
Bridge의 UML 은 GoF 책의 사본에서 상당히 다릅니다 . 이 도구 는 Bridge와 Strategy를 구분할 수 있습니다.
Fuhrmanator

1
Wikipedia는 종종 끔찍한 참조입니다. 당연히 그 잘못된 정보가 페이지에서 제거되었습니다. en.wikipedia.org/w/…
Fuhrmanator

2
내가 얻는 방법은 구현 (전략)을 추상화하거나 인터페이스 (브리지)를 추상화하는 데 동일한 기술이 사용된다는 것입니다. 전략은 동작을 바꾸고, Bridge는 인터페이스를 바꿉니다 (이는 궁극적으로 그러한 인터페이스를 사용한 구현을 바꿉니다). 즉, Bridge는 한쪽에서 표준화 된 인터페이스를 만들고 다른 쪽에서는 다른 인터페이스로 구현을 연결합니다.
Nikaas

55

브리지 패턴은 구조적 패턴입니다 (소프트웨어 구성 요소를 어떻게 구축합니까?). 전략 패턴은 동적 패턴입니다 (소프트웨어에서 동작을 어떻게 실행 하시겠습니까?).

구문은 비슷하지만 목표는 다릅니다.

  • 전략 : 작업을 수행하는 더 많은 방법이 있습니다. 전략을 사용하면 런타임에 알고리즘을 선택할 수 있으며 컴파일 타임에 많은 부작용없이 단일 전략을 수정할 수 있습니다.
  • Bridge : 인터페이스와 클래스의 계층을 분할하고 추상 참조와 결합 할 수 있습니다 ( 설명 참조 ).

3
그래서 구문이 비슷하다면 소프트웨어 동작을 특정 방식으로 실행하기 위해 이러한 패턴 중 하나를 사용하고 있고 또한 그 방식으로 구성 요소를 구축하고 싶기 때문에 깔끔하게 보이게하고 싶다고 말하는 것이 맞을까요?
user20358 2012

11

전략:

  • 전략에 연결된 컨텍스트 : 컨텍스트 클래스 (추상적이지만 실제로는 인터페이스가 아닙니다! 전체 구현이 아닌 특정 동작을 캡슐화하려는 경우)는 전략 인터페이스 참조 및 전략 동작을 호출하는 구현 을 알고 / 포함합니다 . 그것.
  • 의도는 런타임에 동작을 바꾸는 기능입니다.

    class Context {
    
         IStrategy strategyReference;
    
         void strategicBehaviour() {
    
            strategyReference.behave();
         }
    
    }
    

다리

  • 구현에 연결되지 않은 추상화 : 추상화 인터페이스 (또는 대부분의 동작 추상이있는 추상 클래스)는 구현 인터페이스 참조를 알거나 포함하지 않습니다.
  • 의도는 구현에서 추상화를 완전히 분리하는 것입니다.

    interface IAbstraction {
    
        void behaviour1();
    
        .....
    
    }
    
    interface IImplementation {
    
         void behave1();
    
         void behave2();
    
         .....
    
    }
    
    class ConcreteAbstraction1 implements IAbstraction {
    
          IImplementation implmentReference;
    
          ConcreteAbstraction1() {
    
               implmentReference = new ImplementationA() // Some implementation
    
          }
    
          void behaviour1() {
    
                implmentReference.behave1();
    
          }
    
          .............
    
    }
    
    class ConcreteAbstraction2 implements IAbstraction {
    
          IImplementation implmentReference;
    
          ConcreteAbstraction1() {
    
               implmentReference = new ImplementationB() // Some Other implementation
    
          }
    
          void behaviour1() {
    
                implmentReference.behave2();
    
          }
    
          .............
    
    }
    

10

저도 같은 생각을하고 있었지만 최근에는 브리지를 사용해야했고 브리지가 전략을 사용하고 컨텍스트에 추상화를 추가하여 나중에 클라이언트를 변경하지 않고도 더 많은 변경을 수행 할 수 있다는 것을 깨달았습니다. 추상화없이 Strategy를 사용하면 디자인이 유연하지 않아 나중에 클라이언트를 변경해야 할 수 있습니다. 그러나 전체 교량을 사용하면 디자인이 훨씬 더 유연 해집니다. 여기에서 Strategy에서 Bridge 로의 전환이 어떻게 더 많은 유연성을 제공하는지 확인할 수 있습니다. 또한 이제 "비자"와 "마스터"는 카드뿐만 아니라 휴대폰과 칩에서도 사용할 수 있다고 가정합니다. 브리지를 사용하면 해당 지원을 추가하는 것이 훨씬 쉽습니다.

전략 VS Bridge


9

교량 : (구조적 패턴)

브리지 패턴은 추상화와 구현을 분리하고 둘 다 독립적으로 변할 수 있습니다.

다음과 같은 경우이 패턴을 사용합니다.

  1. 추상화와 구현은 컴파일 타임에 결정되지 않았습니다.
  2. 추상화 및 구현은 독립적으로 변경되어야합니다.
  3. 추상화 구현의 변경 사항은 호출자 응용 프로그램에 영향을주지 않아야합니다.
  4. 고객은 구현 세부 사항으로부터 격리되어야합니다.

전략 : (행동 패턴)

전략 패턴을 사용하면 런타임에 알고리즘 제품군의 여러 알고리즘간에 전환 할 수 있습니다.

다음과 같은 경우 전략 패턴을 사용합니다.

  1. 여러 버전의 알고리즘이 필요합니다.
  2. 클래스의 동작은 런타임에 동적으로 변경되어야합니다.
  3. 조건문 피하기

관련 게시물:

Bridge Pattern은 언제 사용합니까? 어댑터 패턴과 어떻게 다릅니 까?

전략 패턴의 실제 사례


4

디자인 패턴 유형

  • 행동 : 패턴은 클래스 또는 객체가 상호 작용하고 책임을 분배하는 방식을 특성화합니다.
  • 구조적 : 패턴은 클래스 또는 객체의 구성을 처리합니다.
  • Creational : 패턴은 객체 생성 과정에 관심이 있습니다.

교량 (구조)

추상화를 구현에서 분리하여 각각 다를 수 있습니다. 독립적으로. 여기에 이미지 설명 입력

리모컨을 가져 가세요. 리모컨에는 1-6 버튼이 있습니다. 이것은 위 다이어그램의 구체적인 클래스입니다. 리모컨이 TV 또는 DVD에 사용되는지 여부에 따라 각 버튼이 다르게 작동합니다. 각 버튼의 기능은 구현 자 인터페이스의 구현에서 추상화됩니다.

이를 통해 각 장치에서 리모컨이 작동하는 방식을 변경할 수 있습니다.

전략 (행동)

알고리즘 패밀리를 정의하고 각 알고리즘을 캡슐화하여 상호 교환 가능하게 만드십시오. 여기에 이미지 설명 입력

전략에서 우리가 원격 시나리오를보고 있다면. "상태"는 컨텍스트의 상태 참조를 변경하여 교체하는 전체 원격입니다. "concreteStateA"(TV 원격) "concreteStateB"(DVD 원격)입니다.

추가 자료 :


3
  1. Strategy Pattern은 행동 결정에 사용되며 Bridge Pattern은 구조 결정에 사용됩니다.

  2. Brigde Pattern은 구현 세부 사항에서 추상 요소를 분리하는 반면, 전략 패턴은 알고리즘을보다 상호 교환 가능하게 만드는 데 관심이 있습니다.

UML의 전략 패턴

UML의 Brigde 패턴

Swift의 전략 패턴 :

protocol PrintStrategy {
   func print(_ string: String) -> String
}

class Printer {
   let strategy: PrintStrategy

   init(strategy: PrintStrategy) {
      self.strategy = strategy
    }

  func print(_ string: String) -> String {
     return self.strategy.print(string)
  }
}

class UpperCaseStrategy: PrintStrategy {
    internal func print(_ string: String) -> String {
        return string.uppercased()
    }
}

class LowerCaseStrategy: PrintStrategy {
    internal func print(_ string: String) -> String {
        return string.lowercased()
    }
}

var lower = Printer(strategy: LowerCaseStrategy())
lower.print("I love Software Patterns")

var upper = Printer(strategy: UpperCaseStrategy())
upper.print("I love Software Patterns")

Swift의 Brigde 패턴 :

protocol Appliance {
   func run()
}

protocol Switch {
   let appliance: Appliance {get set}
   func turnOn()
}

class RemoteControl: Switch {
   var appliance: Appliance

   init(appliance: Appliance) {
       self.appliance = appliance
   }

   internal func turnOn() {
      appliance.run()
   }
}

class TV: Appliance {
   internal func run() {
      print("TV is ON")
   }
}

class Stereo: Appliance {
   internal func run() {
      print("Stereo is ON")
   }
}

var tvRemote = RemoteControl.init(appliance: TV())
tvRemote.turnOn()

var stereoRemote = RemoteControl.init(appliance: Stereo())
stereoRemote.turnOn()

전략 패턴 만이 더 "교환 가능"한 이유는 무엇입니까? 당신이 당신의 코드 예제에서 교환으로 인터페이스에 우리는 코드 때문에,하지 구현, 우리는, 전략, 또는 다리의 구현을 교환 할 수 StereoTV와 코드가 바로 작동합니다.
denis631 19-12-25

2

willcodejavaforfood의 답변에 추가하면 구현에서 동일 할 수 있습니다. 그러나 전략을 사용하여 정렬 전략과 같은 전략을 바꾸는 반면 브리지를 사용하여 두 개체의 구현 (예 : 데이터베이스 래퍼 및 네트워크 어댑터)을 연결하여 클라이언트 코드가 동일한 API에 대해 작업 할 수 있도록합니다. 그래서 이름은 실제로 모든 것을 말합니다.


1

전략 패턴 에 대한 위키에서

전략 패턴의 UML 클래스 다이어그램은 Bridge 패턴의 다이어그램과 동일합니다. 그러나이 두 가지 디자인 패턴은 의도가 동일하지 않습니다. 전략 패턴은 행동을위한 것이지만 브리지 패턴은 구조를위한 것입니다.

컨텍스트와 전략 간의 결합은 추상화와 Bridge 패턴의 구현 간의 결합보다 더 엄격합니다.


마지막 문구를 자세히 설명해 주시겠습니까?
gstackoverflow

1

패턴 비교 (의도 차이, ...)에 대해 이미 언급 한 내용을 추가하기 위해 브리지 패턴도 의도적으로 구조화되어 추상화 계층 구조 측면이 달라질 수 있습니다. C #과 같은 언어에서는 기존 소비자에게 문제를 일으키지 않는 의도 된 변형을 허용하는 방법으로 가상 메서드를 포함하는 추상화 기반이 있음을 의미 할 수 있습니다. 그 외에는 두 패턴이 대부분 동일하게 보일 수 있습니다.


1

전략 패턴은 런타임에 알고리즘 또는 전략을 연결하려는 경우 사용됩니다. 패턴의 범주는 객체의 동작을 다룬다는 것을 의미하기도합니다. 반면에 다리는 구조적 패턴이며 객체의 구조적 계층을 다룹니다. 그것들 사이에 세련된 추상화를 도입하여 구현에서 추상화를 분리합니다. 정제 된 추상화는 연결된 런타임 전략 (전략 패턴)과 혼동 될 수 있습니다. 브리지 패턴은 n 개의 클래스 생성을 방지하는 메커니즘을 제공하여 구조적 측면을 다룹니다.


1

전략 패턴의 경우에만 구현이 다릅니다.

클래스 A가 여러 구현을 사용할 수있는 클래스 B를 사용한다고 가정합니다. 따라서이 경우 B는 런타임에 제공되는 실제 구현으로 추상화됩니다. 이것이 전략 패턴입니다.

이제 A 자체가 추상적이라면. A와 B는 모두 다를 수 있습니다. Bridge 패턴을 사용합니다.


0

나는 그들이 사용되는 맥락에서 그들 사이에 약간의 차이가 있다고 생각합니다.

저는 Bridge 패턴을 사용하여 둘 다 더 큰 개념에 속하는 직교 개념을 분리하여 독립적으로 변화시킵니다. 일반적으로 여러 추상화가 포함됩니다.

IMO, 전략 패턴은 더 간단하거나 더 평평합니다. 확실히 OCP에 제공되지만 반드시 Bridge 패턴과 같은 다른 더 큰 개념의 일부일 필요는 없습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.