设计模式——桥接模式

名称 Bridge
结构  
意图 将抽象部分与它的实现部分分离,使它们都可以独立地变化。
适用性
  • 你不希望在抽象和它的实现部分之间有一个固定的绑定关系。例如这种情况可能是因为,在程序运行时刻实现部分应可以被选择或者切换。
  • 类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充。这时B r i d g e 模式使你可以对不同的抽象接口和实现部分进行组合,并分别对它们进行扩充。
  • 对一个抽象的实现部分的修改应对客户不产生影响,即客户的代码不必重新编译。
  • (C + +)你想对客户完全隐藏抽象的实现部分。在C + +中,类的表示在类接口中是可见的。
  • 有许多类要生成。这样一种类层次结构说明你必须将一个对象分解成两个部分。R u m b a u g h 称这种类层次结构为“嵌套的普化”(nested generalizations )。
  • 你想在多个对象间共享实现(可能使用引用计数),但同时要求客户并不知道这一点。一个简单的例子便是C o p l i e n 的S t r i n g 类[ C o p 9 2 ],在这个类中多个对象可以共享同一个字符串表示(S t r i n g R e p )。
Code Example
  1// Bridge
  2
  3// Intent: "Decouple an abstraction from its implemntation so that the
  4// two can vary independently". 
  5
  6// For further information, read "Design Patterns", p151, Gamma et al.,
  7// Addison-Wesley, ISBN:0-201-63361-2
  8
  9/* Notes:
 10 * Coupling between classes and class libraries is a major maintenance 
 11 * headache. To ease this problem, often the client talks to an 
 12 * abstraction description, which in turn calls an implementation.
 13 * Sometimes these must evolve - when one changes there can be a need 
 14 * to change the other.  The bridge design pattern lets the abstraction 
 15 * and its implementation evolve separately.  
 16 * 
 17 * So, what is the difference between a bridge and an interface? Interfaces
 18 * can be used when creating bridges - but it should be noted that bridges 
 19 * have additional possibilities. Both the abstraction and the 
 20 * implementation may evolve over time and be the parent of derived classes. 
 21 * The operations needed in the implementation could be defined in an 
 22 * interface if there are no standard methods which are available at the 
 23 * top-level of the implementation.   
 24 * 
 25 */

 26 
 27namespace Bridge_DesignPattern
 28{
 29    using System;
 30
 31    class Abstraction 
 32    {
 33        protected Implementation impToUse;
 34
 35        public void SetImplementation(Implementation i)
 36        {
 37            impToUse = i;
 38        }

 39
 40        virtual public void DumpString(string str)
 41        {
 42            impToUse.DoStringOp(str);                   
 43        }

 44    }

 45
 46    class DerivedAbstraction_One : Abstraction 
 47    {
 48        override public void DumpString(string str)
 49        {
 50            str += ".com";
 51            impToUse.DoStringOp(str);            
 52        }
        
 53    }

 54
 55    class Implementation 
 56    {
 57        public virtual void DoStringOp(string str)
 58        {
 59            Console.WriteLine("Standard implementation - print string as is");
 60            Console.WriteLine("string = {0}", str);
 61        }
        
 62    }

 63
 64    class DerivedImplementation_One : Implementation 
 65    {
 66        override public void DoStringOp(string str)
 67        {
 68            Console.WriteLine("DerivedImplementation_One - don't print string");
 69        }
    
 70    }

 71
 72    class DerivedImplementation_Two : Implementation 
 73    {
 74        override public void DoStringOp(string str)
 75        {
 76            Console.WriteLine("DerivedImplementation_Two - print string twice");
 77            Console.WriteLine("string = {0}", str);
 78            Console.WriteLine("string = {0}", str);
 79        }
    
 80    }

 81    
 82    /// <summary>
 83    ///    Summary description for Client.
 84    /// </summary>

 85    public class Client
 86    {
 87        Abstraction SetupMyParticularAbstraction() 
 88        {
 89            // we localize to this method the decision which abstraction and
 90            // which implementation to use. These need to be decided 
 91            // somewhere and we do it here. All teh rest of the client 
 92            // code can work against the abstraction object. 
 93            Abstraction a = new DerivedAbstraction_One();
 94            a.SetImplementation(new DerivedImplementation_Two());
 95            return a;
 96        }

 97
 98        public static int Main(string[] args)
 99        {         
100            Client c = new Client();
101            Abstraction a = c.SetupMyParticularAbstraction();
102                
103            // From here on client code thinks it is talking to the 
104            // abstraction, and will not need to be changed as 
105            // derived abstractions are changed. 
106
107            // more client code using the abstraction goes here 
108            // . . . 
109            a.DumpString("Clipcode");
110
111            return 0;
112        }

113    }

114}

115
116

posted @ 2005-06-28 08:14  DarkAngel  阅读(899)  评论(0编辑  收藏  举报