在软件系统中,有些类由于其本身的固有特性,使得它具有两个或多个变化维度,这种变化维度又称为变化原因。对于这种多维度变化的系统,桥接模式提供了一套完整的解决方案,并且降低了系统的复杂性。
模式动机:
设想如果要绘制矩形、圆形、椭圆、正方形,我们至少需要4个形状类,但是如果绘制的图形需要具有不同的颜色,如红色、绿色、蓝色等,此时至少有如下2种解决办法:
1.为每种形状都提供一套各种颜色的版本,如下:
4种形状,3种颜色,我们需要4*3=12个类,简直就是class boom。而且每增加一个形状,我们都要增加3个颜色类。增加一种颜色,其他形状都要增加。
2.第二种方案是设计4个形状类,3个颜色类,根据需要对形状和颜色进行组合。
需要的类是4+3=7个。在该设计方案中,如果需要增加一种新的形状或新的颜色,只需要增加一个新的形状类和颜色类几口。
很明显,设计方案2要好的多,就是我吗所说的桥接模式,桥接模式将继承关系转换为关联关系,从而降低了类与类之间的耦合,减少了代码编写量。
定义:
Decouple an abstraction from its implementation so that the two can vary independently.
将抽象与实现分离,使他们能独立变化。
The classes and/or objects participating in this pattern are:
- Abstraction (BusinessObject)
- defines the abstraction's interface.
- maintains a reference to an object of type Implementor.
- RefinedAbstraction (CustomersBusinessObject)
- extends the interface defined by Abstraction.
- Implementor (DataObject)
- defines the interface for implementation classes. This interface doesn't have to correspond exactly to Abstraction's interface; in fact the two interfaces can be quite different. Typically the Implementation interface provides only primitive operations, and Abstraction defines higher-level operations based on these primitives.(定义类的实现接口,该接口不一定要与Abstract的接口完全一致,事实上这2个接口可以完全不同,一般来讲,Implementor接口仅提供基本操作,而Abstraction则定义了基于这些基本操作的较高层次的操作。)
- ConcreteImplementor (CustomersDataObject)
- implements the Implementor interface and defines its concrete implementation.
如何理解将抽象和实现分离?
可以这样理解:对一个事物进行抽象,得到了一个行为。 比如对Shape进行抽象,得到了Draw的行为。Draw是在哪里实现的?不是在它抽象而来的类Shape,而是在另外一个类实现的。哪个类呢?Drawing类。
Draw是从Shape抽象出来的行为,但是不在Shape中予以实现。这就是抽象和实现分离。
为什么要这样呢?因为Draw的方法可能不同,比如可以用实线,也可以用虚线。为了更好的隐藏变化,所以将其分离。由于本文不是介绍Bridge模式,不再深入介绍它的好处。
参考:http://www.cnblogs.com/idior/articles/97283.html
桥接模式实例:
现在需要提供大小中3种型号的画笔,能够绘制5种不同的颜色。我们简化这个过程。(代码中型号为大小2中,颜色为Red,Blue,Green3种)。
Color类:
public abstract class Color { abstract void bepaint(String penType,String name); }
继承的类:
public class Red extends Color { void bepaint(String penType, String name) { System.out.println(penType+" 红色的"+name+"."); } } public class Blue extends Color { void bepaint(String penType, String name) { System.out.println(penType+"蓝色的"+name+"."); } } public class Green extends Color { void bepaint(String penType, String name) { System.out.println(penType+"绿色的"+name+"."); } }
画笔:
public abstract class Pen { protected Color color; public void setColor(Color color) { this.color=color; } public abstract void draw(String name); }
Pen中有Color类,从而建立了关联。也就是说在Pen及其子类中可以调用在Color接口中定义的方法,在Pen中定义了抽象业务方法draw(),在其子类中将实现该方法。
public class SmallPen extends Pen { public void draw(String name) { String penType="小号毛笔绘制"; this.color.bepaint(penType, name); } } public class LargePen extends Pen { public void draw(String name) { String penType="大号毛笔绘制"; this.color.bepaint(penType, name); } }
Main类:
public class Main { public static void main(String[] args) { Color color=new Red(); Pen pen=new SmallPen(); pen.setColor(color); pen.draw("--你好"); pen.setColor(new Blue()); pen.draw("--你好"); pen=new LargePen(); pen.setColor(new Red()); pen.draw("你好"); } }