何时使用bridge模式:
从设计模式书上的得知较多的应用场景有:
1.你不希望在抽象和它的实现部分之间有一个固定的绑定关系。例如这种情况可能是因为,在程序运行时刻实现部分应可以被选择或者切换。(一个对象的抽象对应多个行为)
2.类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充。这时Bridge模式使你可以对不同的抽象接口和实现部分进行组合,并分别对他们进行扩充(多个抽象与多个行为对应时且可以互相配对).
3.对一个抽象的实现部分的修改应对客户不产生影响,既客户的代码不必重新编译.
上面的描述中产生了两个概念,对象的抽象和对象的行为,什么是抽象,什么是行为?
答:个人认为抽象是一个很有高度的描述,比如领导说我要那块土地做开发,这就是抽象,因为他并没有说明是怎么拿下那块土地,拿土地
可以抢回来,偷回来,买回来,逼人行贿送过来等各种方法皆可,具体的实施就是行为。上述的案例如果领导只要一块土地,或者说领导规定只
要是土地都给我抢回来(黑社会老大0-0),那么也就不需要bridge模式了,直接绑定死抽象和行为既可,代码量也会简单很多,但是如果领导
没有规定死拿土地的行为,今天拿这块地是买的,明天拿那块地偷的,后天拿那块地是别人行贿过来的,那么这时候就适用适用桥接模式了,适
用上面所述的场景1。
在来一个煮咖啡的例子,假设我要煮一杯咖啡,但是咖啡种类有很多,有黑咖啡,卡布奇诺,拿铁,同时咖啡还有中杯,大杯,小杯之分。
所以这些组合起来就有大杯黑咖啡,大杯卡布奇诺,中杯拿铁.....如果抽象和行为绑定死,那么就需要根据不同的组合写不同的子类来实现了,
这是一件很痛苦的事,因此利用bridge模式的概念,首先抽象部分可以分离出我要一杯大杯咖啡,我要一杯中杯咖啡,我要一杯小杯咖啡。行为
方面自然是煮咖啡给客户咯,不同种类的咖啡有不同的材料和不同的煮法,这就是分离出来的行为,这样我们就可以任意组合抽象和行为之间提
供给客户合心意的咖啡。
代码实例:
package com.gof.chapter4.bridge.simple;
/**
* 咖啡的抽象类,其子类主要用来描述是要大杯咖啡,小杯咖啡还是中杯
* 咖啡
**/
public abstract class Coffee {
CoffeeImp coffeeImp;
public void setCoffeeImp(CoffeeImp _coffeeImp){
this.coffeeImp = _coffeeImp;
}
public CoffeeImp getCoffeeImp(){return this.coffeeImp;}
public abstract void makeCoffee();
}
package com.gof.chapter4.bridge.simple;
/**
* 煮咖啡的抽象类
*/
public abstract class CoffeeImp {
public abstract void makeCoffeeImp();
}
- Abstraction(比如上述例子中的Coffee)--定义抽象类的接口。--维护一个指向Implementor类型对象的指正.
- RefinedAbstraction(比如上述例子的SuperSizeCoffee) -- 扩充由Abstraction定义的接口
- Implementor(比如上述例子中的CoffeeImp) -- 定义实现类的接口,该接口不一定要与Abstraction的接口完全一致;事实上这两个接口可以完全不同。一般来讲,Implementor接口仅提供基本操作,而Abstraction则定义了基于这些基本操作的较高层次的操作.
- ConcreateImplementor(比如上述例子中的Cappuccino) -- 实现Implementor接口并定义它的具体实现.
我所说的有趣的事是我们可以把Abstraction理解为定义了一个公司经理应该做的事情,而RefinedAbstraction则是对应各个级别经理他们具体做的事,而Implementor则定义了一个公司员工该做的事,ConcreateImplementor则定义了各个员工具体做的事。所以说领导说的话都是抽象的- -~~~好吧顺便吐槽下,抽象的东西永远不会错,所以说领导说的永远不会错,只有下面的人理解错了,做错了,悲剧啊。
最后PS下:如果对象的产生复杂或者节省内存开销可以使用到factory模式和singleton模式。这个具体自己想吧......