Bridge模式(桥接模式):
定义:将抽象与其实现解耦,使它们都可以独立地变化。(注:这里的实现指抽象类及其派生类用来实现自己的对象)
实现:将实现封装在一个抽象类中。在要实现的抽象的基类中包含一个实现的句柄。
结构图:
其中Abstraction为要实现的对象接口,Implementor为具体的实现类接口。Abstraction的派生类使用Implementor的派生类,却无需知道自己具体使用哪一个ConcreteImplementor。
代码示例:
考虑这样的软件需求:需要编写一个程序,使用两个绘图程序(DP1和DP2)之一绘制矩形和圆形。
首先先定义实现,Drawing为实现的基类,V1Drawing和V2Drawing为Drawing的子类,V1Drawing使用绘图程序DP1画线和画圆,V2Drawing使用绘图程序DP2画线和画圆。
1 public abstract class Drawing { 2 public abstract void DrawLine(double x1, double y1, double x2, double y2); 3 public abstract void DrawCircle(double x, double y, double r); 4 } 5 6 public class V1Drawing : Drawing { 7 public override void DrawLine(double x1, double y1, double x2, double y2) { 8 dp1.DrawLine(x1, y1, x2, y2); 9 } 10 11 public override void DrawCircle(double x, double y, double r) { 12 dp1.DrawCircle(x, y, r); 13 } 14 15 private DP1 dp1 = new DP1(); 16 } 17 18 public class V2Drawing : Drawing { 19 public override void DrawLine(double x1, double y1, double x2, double y2) { 20 dp2.DrawLine(x1, y1, x2, y2); 21 } 22 23 public override void DrawCircle(double x, double y, double r) { 24 dp2.DrawCircle(x, y, r); 25 } 26 27 private DP2 dp2 = new DP2(); 28 }
然后定义抽象,也就是使用实现的对象的基类,这里就是矩形和圆形的基类(Sharp),Sharp里有一个Drawing的句柄并由构造函数传进来,而Sharp并不知道Drawing具体的类型(V1Drawing还是V2Drawing),这样就是将抽象和实现隔离开来了(解耦)。
1 public abstract class Sharp { 2 public Sharp(Drawing drawing) { 3 this.drawing = drawing; 4 } 5 6 public abstract void Draw(); 7 8 protected void DrawLine(double x1, double y1, double x2, double y2) { 9 this.drawing.DrawLine(x1, y1, x2, y2); 10 } 11 12 protected void DrawCircle(double x, double y, double r) { 13 this.drawing.DrawCircle(x, y, r); 14 } 15 16 private Drawing drawing; 17 }
后面就是定义抽象的派生类,
1 public class Rectangle : Sharp { 2 public Rectangle(Drawing drawing, double x1, double y1, double x2, double y2) 3 : base(drawing) { 4 this.x1 = x1; 5 this.y1 = y1; 6 this.x2 = x2; 7 this.y2 = y2; 8 } 9 10 public override void Draw() { 11 DrawLine(x1, y1, x2, y1); 12 DrawLine(x2, y1, x2, y2); 13 DrawLine(x1, y1, x1, y2); 14 DrawLine(x1, y2, x1, y1); 15 } 16 17 private double x1, y1, x2, y2; 18 } 19 20 public class Circle : Sharp { 21 public Circle(Drawing drawing, double x, double y, double r) 22 : base(drawing) { 23 this.x = x; 24 this.y = y; 25 this.r = r; 26 } 27 28 public override void Draw() { 29 DrawCircle(x, y, r); 30 } 31 32 private double x, y, r; 33 }
最后就是执行程序
1 public class Client { 2 static void Main(string[] args) { 3 List<Sharp> sharps = new Factory().GetSharps(); 4 foreach(var each in sharps) { 5 each.Draw(); 6 } 7 } 8 }
总结:
通过Bridge模式可以将抽象和实现解耦,可以独立地变化,比如增加一个椭圆形状或者多了一个绘图程序DP3,实现起来就变得容易了。
同时应该遵循应对变化的基本策略:找到变化并封装之;优先使用对象聚集而不是类继承。