Presentation is loading. Please wait.

Presentation is loading. Please wait.

Http://cutewebi.tistory.com cutewebi@gmail.com 김희정 Bridge Pattern.

Similar presentations


Presentation on theme: "Http://cutewebi.tistory.com cutewebi@gmail.com 김희정 Bridge Pattern."— Presentation transcript:

1 http://cutewebi.tistory.com cutewebi@gmail.com 김희정
Bridge Pattern

2 Bridge Pattern 현실 세계의 다리가 강으로 나누어진 양쪽 장소를 연결하는 것처럼 ,
현실 세계의 다리가 강으로 나누어진 양쪽 장소를 연결하는 것처럼 , Bridge 패턴도 두 장소를 연결하는 역할. Bridge 패턴이 다리를 놓을 곳? '기능의 클래스 계층’ '구현의 클래스 계층’

3 새로운 '기능'을 추가하고 싶을때 Something + SomethingGood
(새로운 메소드를 추가하려고 할 때) Something의 하위 클래스(자식 클래스, 파생 클래스, 확장 클래스)로서 SomethingGood 클래스를 만든다. 이것으로 소규모의 클래스 계층이 발생한다. Something + SomethingGood

4 새로운 '기능'을 추가하고 싶을때 Something + SomethingGood + SomethingBetter
상위 클래스 : 기본적인 기능을 가지고 있음. 하위 클래스 : 새로운 기능을 추가. '기능의 클래스 계층'이라고 함. SomethingGood 클래스에 또 다시 새로운 기능을 추가하고 싶으면 SomethingGood 클래스의 하위 클래스로서 SomethingBetter 클래스를 만든다. 이것으로 기능의 클래스 계층이 좀 더 깊어짐. 일반적으로 클래스 계층은 너무 깊게 하지 않는 것이 좋다. Something + SomethingGood + SomethingBetter

5 새로운 '구현'을 추가하고 싶을 때 추상 클래스가 일련의 메소드들을 추상 메 소드로서 선언하고 인터페이스(API)를 규정.
하위 클래스 쪽에서 그 추상 메소드를 실제 로 구현. 이와 같은 상위 클래스와 하위 클래스의 역 활 분담에 의해 부품으로서의 가치(교환 가 능성)가 높은 클래스를 만들 수 있다.

6 새로운 '구현'을 추가하고 싶을 때 AbstractClass + ConcreteClass
다음과 같은 소규모의 클래스 계층이 만들 어진다. AbstractClass + ConcreteClass

7 새로운 '구현'을 추가하고 싶을 때 AbstractClass + ConcreteClass
그렇지만 여기서 사용되고 있는 클래스 계층은 기능을 추가하기 위한 것이 아니라 역할 분담을 위해 클래스 계층이 사용. 상위 클래스 : 추상 메소드에 의해 인터페이스(API)를 규정. 하위 클래스 : 구현 메소드에 의해 그 인터페이스(API)를 구현. AbstractClass의 다른 구현을 만들고 싶으면 하위 클래스를 AnotherConcreteClass로 한다. AbstractClass + ConcreteClass + Another ConcreteClass

8 Example 기능(추상화) 구현

9 클래스의 역활 Client의 역할 Abstraction(추상화)의 역할
Bridge 패턴을 사용하는 객체. Abstraction(추상화)의 역할 '기능의 클래스 계층'의 최상위에 있는 클래스. Implementor 역할의 메소드를 사용해서 기본적인 기능만 기술되어 있는 클래스. (이 인스턴스는 Implementor 역할을 가짐) RefinedAbstraction(개선된 추상화)의 역할 Abstraction 역할에 기능을 추가한 역할. Implementor(구현자)의 역할 '구현의 클래스 계층'의 최상위에 있는 클래스. Abstraction 역할의 인터페이스(API)를 구현하기 위한 메소드를 규정하는 역할. ConcreteImplementor(구체적인 구현자)의 역할 Implementor 역할의 인터페이스(API)를 구체적으로 구현하는 역할.

10 Bridge Pattern 클래스의 구현으로부터 인터페이스를 분리 하는데 사용. 추상화 정도에 의한 계층으로 구분되어 있 고
이를 구현하는데 있어 몇 개의 계층으로 나 누는 경우에 유용한 패턴. 추상화 정도와 구현에 따라 완전히 구별되 는 여러 클래스로 나누기 보다는 이를 동적으로 조합되는 몇 개의 상이한 클 래스로 관리. 

11 Bridge 패턴을 사용하는 경우 구현을 run-time binding 할 경우
인터페이스의 결합과 여러가지의 구현으로 클래스를 많이 만들어야 하는 경우 여러 객체에서 구현을 공유하려고 할 때 클래스 구조를 수직으로 나눌 필요가 있을 때

12 구성 요소 클래스의 인터페이스를 정의하는 추상화 (Abstraction)
해당 인터페이스를 상속하고 구현하는 정제 된 추상화(Refined Abstraction) 구현 클래스에 대한 인터페이스를 정의하는 구현자(Implementor) 구현 클래스인 ConcreteImplementor

13 구조

14 역활 Abstraction의 역할 RefindedAbstraction의 역할 Implementor의 역할
‘기능의 클래스 계층’의 최상위에 있는 클래스. Implementor 역할의 메소드를 사용해서 기본적인 기능만 기술되어 있는 클래스. 이 인스턴스는 Implementor 역할을 가지고 있다. RefindedAbstraction의 역할 Abstraction 역할에다 기능을 추가한 역활. Implementor의 역할 ‘구현의 클래스 계층’의 최상위에 있는 클래스. Abstractor 역할의 인터페이스(API)를 구현하기 위한 메소드를 규정하는 역할. ConcreteImplementor의 역할 Implementor 역할의 인터페이스(API)를 구체적으로 구현하는 역할.

15 Adapter 패턴과 Bridge 패턴 하나의 클래스가 한 종류의 인터페이스를 다른 종 류의 인터페이스로 변환하기 위해 사용되었기 때 문에 Adapter패턴과 매우 닮았다고 생각하기 쉽다. 그러나 Adapter 패턴은 한 개 이상의 클래스 인터페이스를 특정 클래스의 인터페이스와 동일하게 간주하기 위해 의도된 것이다. 이와 반대로 Bridge 패턴은 개발자가 클라이언트의 코드 내용을 변경하지 않고도 구현 내용을 바꾸거나 대체할 수 있도록 클래스의 인터페이스와 구현 내용을 분리시킨 것이다.

16 Example_DataList 데이터를 나타내는 리스트 방법에서 몇 가 지 변경사항이 필요하다 가정해보자.
예를 들어, 생산물의 목록을 알파벳 순으로 정렬하고자 할 수도 있다. 이렇게 하기 위해서는 상속된 클래스들의 수정을 필요하게 된다. 우리가 나타내야 할 것이 두 개 이상이 된다 면 더더욱 끔찍한 작업이 될 것이다.

17 Example_DataList 변경된 내용을 나타내기 위해 새로운 클래 스를 파생시키는 것보다는
Bridge를 만들어 작업하는 것이 더 나을 것 이다.

18 Example_Two steps

19 Example_Switch

20 Example_Window

21 Example_Seat

22 sample code in C# Structural example
using System; namespace DoFactory.GangOfFour.Bridge.Structural {   // MainApp test application   class MainApp   {     static void Main()     {       Abstraction ab = new RefinedAbstraction();       // Set implementation and call       ab.Implementor = new ConcreteImplementorA();       ab.Operation();       // Change implemention and call       ab.Implementor = new ConcreteImplementorB();       ab.Operation();       // Wait for user       Console.Read();     }   }

23 sample code in C# Structural example
  // "Abstraction"   class Abstraction   {     protected Implementor implementor;     // Property     public Implementor Implementor     {       set{ implementor = value; }     }     public virtual void Operation()     {       implementor.Operation();     }   }   // "Implementor"   abstract class Implementor   {     public abstract void Operation();   }

24 sample code in C# Structural example
  // "RefinedAbstraction"   class RefinedAbstraction : Abstraction   {     public override void Operation()     {       implementor.Operation();     }   }

25 sample code in C# Structural example
  // "ConcreteImplementorA"   class ConcreteImplementorA : Implementor   {     public override void Operation()     {       Console.WriteLine("ConcreteImplementorA Operation");     }   }   // "ConcreteImplementorB"   class ConcreteImplementorB : Implementor   {     public override void Operation()     {       Console.WriteLine("ConcreteImplementorB Operation");     }   } }

26 sample code in C# Structural example

27 sample code in C# Real World example
using System; using System.Collections; namespace DoFactory.GangOfFour.Bridge.RealWorld {   // MainApp test application   class MainApp   {     static void Main()     {       // Create RefinedAbstraction       Customers customers =         new Customers("Chicago");       // Set ConcreteImplementor  customers.Data = new CustomersData();       // Exercise the bridge       customers.Show();       customers.Next();       customers.Show();       customers.Next();       customers.Show();       customers.New("Henry Velasquez");       customers.ShowAll();       // Wait for user       Console.Read();     }   }

28 sample code in C# Real World example
  // "Abstraction"   class CustomersBase   {     private DataObject dataObject;     protected string group;     public CustomersBase(string group)     {       this.group = group;     }     

29 sample code in C# Real World example
// Property     public DataObject Data     {       set{ dataObject = value; }       get{ return dataObject; }     }     public virtual void Next()     {       dataObject.NextRecord();     }    public virtual void Prior()     {       dataObject.PriorRecord();     }     public virtual void New(string name)     {       dataObject.NewRecord(name);     }     public virtual void Delete(string name)     {    dataObject.DeleteRecord(name);   }     public virtual void Show()     {       dataObject.ShowRecord();     }     public virtual void ShowAll()     {       Console.WriteLine("Customer Group: " + group);       dataObject.ShowAllRecords();     }   }

30 sample code in C# Real World example
  // "RefinedAbstraction"   class Customers : CustomersBase   {     // Constructor     public Customers(string group) : base(group)     {       }     public override void ShowAll()     {       // Add separator lines       Console.WriteLine();       Console.WriteLine (" ");       base.ShowAll();       Console.WriteLine (" ");     }   }   // "Implementor"   abstract class DataObject   {     public abstract void NextRecord();     public abstract void PriorRecord();     public abstract void NewRecord(string name);     public abstract void DeleteRecord(string name);     public abstract void ShowRecord();     public abstract void ShowAllRecords();   }

31 sample code in C# Real World example
  // "ConcreteImplementor"   class CustomersData : DataObject   {     private ArrayList customers = new ArrayList();     private int current = 0;     public CustomersData()     {       // Loaded from a database       customers.Add("Jim Jones");       customers.Add("Samual Jackson");       customers.Add("Allen Good");       customers.Add("Ann Stills");       customers.Add("Lisa Giolani");     }     public override void NextRecord()     {       if (current <= customers.Count - 1)       {         current++;       }     }     public override void PriorRecord()     {       if (current > 0)       {         current--;       }     }    

32 sample code in C# Real World example
 public override void NewRecord(string name)     {       customers.Add(name);     }     public override void DeleteRecord(string name)     {       customers.Remove(name);     }     public override void ShowRecord()     {       Console.WriteLine(customers[current]);     }     public override void ShowAllRecords()     {       foreach (string name in customers)       {         Console.WriteLine(" " + name);       }     }   } }

33 sample code in C# Real World example

34 Example_Image

35 Example_Image

36 Example_Image C# Implementation
// Structural Pattern:BRIDGE //Abstract class for all image paintings using System; class Image //Base class for OS implemenations interface ImageImp public void SetImageImp(ImageImp ip) { void DoPaint(string str); impToUse = ip; } //Windows specific implemenation public virtual void Method(string s1) class WinImp : ImageImp public void DoPaint(string str) protected ImageImp impToUse; Console.WriteLine(str + " WIN OS");

37 Example_Image C# Implementation
//BMP specific paintings im.SetImageImp(win); class BMPImage : Image return im; { override public void Method(string s1) class MyMain string s2 = s1 + " BMP IMAGE"; impToUse.DoPaint(s2); public static void Main() } MyPaint mp = new MyPaint(); //Client Image im = mp.SetUpMethod(); class MyPaint im.Method("PAINTING-->"); public Image SetUpMethod() Image im = new BMPImage(); // BMP IMAGE ImageImp win = new WinImp();// WIN OS

38 장점 해당 인터페이스를 클라이언트의 프로그램에서 일정 하게 유지하기 위해 의도되는 패턴.
개발자가 출력하거나 사용하는 실제 클래스를 변경. 개발자가 사용자 인터페이스 모듈의 어려운 부분을 다시 컴파일해야 할 수고를 덜어줌. Bridge 패턴 자체와 실제 최종 출력 클래스 부분만 다시 컴파일. 개발자는 클래스의 구현 내용과 Bridge클래스를 각각 별도로 상속할 수 있으며, 일반적으로 서로 지나치게 상호 작용할 필요가 없다. 클라이언트 프로그램으로부터 구현 내용을 훨씬 쉽게 감출 수 있다.

39 활용법 및 단점 추상과 구현이 한 클래스에 같이 붙어있지 않고 그 들을 분리하여 확장을 쉽게 하고 싶을 때 사용.
추상과 구현이 분리되어 결합도가 낮아진다. 추상은 그대로 두고 구현만 프로그램 실행중에 변 경해도 다른 클라이언트에게 영향을 미치지 않게 할 경우에 적용. 그 결과 추상과 구현을 서로 독립적으로 확장할수 있어 확장성이 개선. 여러 플랫폼에서 사용해야 할 그래픽스 및 윈도우 처리 시스템에서 유용. 인터페이스와 실제 구현부를 서로 다른 방식으로 변경해야 하는 경우 유용. 디자인이 복잡해진다는 단점.

40 적용영역 추상 클래스 혹은 인터페이스와 구현 클래스 사이의 항구적인 바인딩(permanent binding)을 피하고자 하는 경우 추상 클래스 혹은 인터페이스와 구현 클래스가 별도로 상속을 통해 확장되어야 하는 경우 구현 클래스에서의 변화가 클라이언트에 영향 을 미치지 않기를 원하는 경우 다수의 객체들이 하나의 구현 클래스를 공유하 면서 이러한 사실을 모르게 하고자 하는 경우

41 적용결과 인터페이스와 구현 사이의 결합도를 낮춘다 (decoupling).
추상 클래스 혹은 인터페이스와 구현 클래 스가 독립적인 계층 구조를 지니기 때문에 확장성이 개선된다. 클라이언트가 구현 클래스에 대한 세부 내 용을 알 수 없다.

42 관련패턴 Template Method Abstract Factory Adapter
구현 클래스 계층을 이용. 상위 클래스에서는 추상 메소드를 사용해서 프로그래밍을 실행하고 하위 클래스에서는 그 추상 메소드를 구현. Abstract Factory Bridge 패턴에 등장하는 ConcreteImplementor 역할을 환경에 맞춰서 적절히 구축하기 위해 Abstract Factory 패턴이 이용되는 경우도 있음. Adapter Bridge 패턴은 기능의 클래스 계층과 구현의 클래스 계층을 확실히 분리한 다음에 연결시키는 패턴. Adapter 패턴도 기능은 비슷하지만 인터페이스(API)가 다른 클래스를 결합시키는 패턴.

43 관련패턴 Example (Example_GUI Component)

44 다른 패턴과의 비교 Adapter는 설계 후에 동작되고, Bridge는 설 계되기 이전에 작동한다. [GoF]
Bridge는 추상과 구현이 독립적으로 변하도 록 전면에 설계된다. Adapter는 관련없는 클 래스들이 함께 작동하도록 새롭게 개선한다. [GoF] 인터페이스 클래스는 구현 클래스의 생성을 직접하지 않고 위임한다. 따라서, 구현객체 를 만드는 설계는 보통 Abstract Factory 패턴 을 사용한다. [Grand, Patterns in Java]

45 다른 패턴과의 비교 State와 Strategy, Bridge는 비슷한 해결 구조다. 차이는 다른 문제를 해결한다는 것이다. [Coplien, Advanced C++] State와 Bridge 구조는 동일하다. (Bridge는 계 층구조를 허용하지만, State는 하나만 허용한 다는 것만 제외). 이 두가지 패턴은 같은 구조를 사용해서 다른 문제를 해결한다. State는 객체 의 행동이 객체의 상태에 따라 바뀌도록 하지 만, 반면에 Bridge의 목적은 추상과 구현을 분 리하여 각각이 독립적으로 변화할 수 있도록 하는 것이다. [Coplien, C++ Report]

46 감사합니다 Q&A


Download ppt "Http://cutewebi.tistory.com cutewebi@gmail.com 김희정 Bridge Pattern."

Similar presentations


Ads by Google