原文:http://chjking.blog.163.com/blog/static/6439511120081152534252/
看了网上一些关于咖啡加奶的例子,觉得真是天下文章一大抄,不管好的坏的都照搬,于是在原有的基础上进行了重新编写,代码也已经过测试。
Bridge定义 :
将抽象和行为划分开来,各自独立,但能动态地结合。这句话是对的,但理解起来较为困难。可以这么理解,抽象是一个事物的本身的特征,行为是一个事物可以做的动作,特征是相对独享的,行为是可以共享的。举例:不同的数据库,它们具有不同的特征,比如URL,驱动这些每个数据库都不能共享,就是所谓抽象。而每个数据库都具有类似的行为,插入,删除,修改等等,这些操作是可以和共享的,就是所谓行为。
为什么使用?
一句话可以概括,解耦合。
以数据库为例,当使用不同数据库时,不需要对其行为部分代码进行修改,当添加新的行为时,也不需要对数据库特征部分进行修改,就可以使所有存在数据库共享这一行为。
如何实现?
以下代码改编自网上:
一杯咖啡为例,有中杯和大杯之分,同时还有加奶 不加奶之分. 假如用单纯的继续,这四个具体实现(中杯 大杯 加奶 不加奶)之间有概念重叠,因为有中杯加奶,也有中杯不加奶, 假如再在中杯这一层再实现两个继续,很显然混乱,扩展性极差.那我们使用Bridge模式来实现它.
首先是咖啡可以进行的行为的父接口:(加奶,不加奶)
public interface CoffeeImpl {
public String pourCoffeeImpl();}下面两个是行为的具体的实现子类
加奶
public class MilkCoffeeImpl implements CoffeeImpl {
public String pourCoffeeImpl() {
System.out.println("add milk"); return "add milk"; }}
不加奶
public class FragrantCoffeeImpl implements CoffeeImpl {
public String pourCoffeeImpl() {
System.out.println("no milk"); return "no milk"; }}
下面是咖啡的抽象父类,也就是区分大杯和中杯
public abstract class Coffee {
CoffeeImpl coffeeImpl;public CoffeeImpl getCoffeeImpl() {
return coffeeImpl; }public void setCoffeeImpl(String way) {
this.coffeeImpl = ActionFactory.createCoffeeImpl(way); } public abstract void pourCoffee();}
下面是2个抽象的具体实现子类
大杯
public class BigCoffee extends Coffee {
public BigCoffee(String way) { pourCoffee(); this.setCoffeeImpl(way); this.coffeeImpl.pourCoffeeImpl(); } @Override public void pourCoffee() { System.out.print("Big coffee "); }}
中杯
public class MiddleCoffee extends Coffee {
public MiddleCoffee(String way) { pourCoffee(); this.setCoffeeImpl(way); this.coffeeImpl.pourCoffeeImpl(); }@Override
public void pourCoffee() { System.out.print("Middle coffee "); }}
下面是一个简单工厂,用来动态确定咖啡的行为,究竟是加奶还是不加奶,当然可以使用自己定义的方法来实现这个功能,这里我选择简单工厂。
public class ActionFactory {
public static CoffeeImpl createCoffeeImpl(String way) { if("milk".equals(way)) { return new MilkCoffeeImpl(); } else if("fragrant".equals(way)) { return new FragrantCoffeeImpl(); } else { return null; } } }
到此为止,bridge模式就完成了,读者可以很方便的自己试试着这个基础上添加自己的咖啡抽象,比如小杯咖啡,还能添加咖啡行为,比如加糖不加糖,记得需要对简单工厂进行修改。
最后就是测试类
public class Test {
/**
* @param args */ public static void main(String[] args) { //中杯不加奶 Coffee coffee1 = new MiddleCoffee("fragrant"); //大杯加奶 Coffee coffee2 = new BigCoffee("milk"); //中杯加奶 Coffee coffee3 = new MiddleCoffee("milk"); //大杯不加奶 Coffee coffee4 = new BigCoffee("fragrant"); }}
完成了,输出结果是:
Middle coffee no milk
Big coffee add milkMiddle coffee add milkBig coffee no milk可以看到调用很方便,类决定了什么样的咖啡(抽象),而参数决定了什么样的操作(行为)。