桥接模式
关于桥接模式的定义:
将抽象与行为相分离,使得他们各自可以独立变化,然后可通过动态组合得到想要的结果,目标是实现解耦。桥接模式的类关系图如下:
现在举一个例子来说明桥接模式.
以最常用的咖啡问题来说明。现在模拟的场景是这样子的:
咖啡有分大杯和中杯,同时咖啡里面可以选择加牛奶,也可以选择加苹果汁,也可以什么都不加。因为刚开张,所以目前就只有大杯和中杯,未来可能会有更多规格的杯子,同时也会有更多的调料给客人选择,设计一个具有弹性的程序 |
分析:按照目前的情况,最简单的做法就是分别写出6种类,来表示六种不同组合的咖啡。
我们可以分析到这种做法虽然和直观,但是会存在很多问题,其中之一就是这6个类的每一个类都已经具体的代表了一种咖啡,换句话说,这几个类是没办法复用的,这当然是我们不想要的,另外一个问题就是,如果添加一个规格的杯子,比如小杯,又要再写小杯中分别加不同调料的类,可想而知,后面店的规模大起来的话,会造成类的“炸弹”。
我们想要的结果是,当增加一种调料时只需要增加一个类,增加一个杯子规模的时候也只需要增加一个类就可以达到目的,这就需要用到桥接模式了。
桥接模式分析法:把属性和行为分别抽象并独立开来,行为就是加牛奶加苹果汁等,属性就是大杯中杯之类的。我们的目的就是把行为和属性完全没有耦合,通过组合来形成不同的咖啡,通俗点说,例如我们只提供的各种零件,让使用者去使用而已,不提供整合好的东西。
请看分析的类图:
具体来看看代码的实现:
/** * 咖啡的行为 * @author ChenST * */ public interface Action { /** * 做事情 * @return */ public String doThing(); }
/** * 加牛奶的行为 * @author ChenST */ public class AddMilkAction implements Action { @Override public String doThing() { return "加了[牛奶]"; } }
/** * 什么也不加的行为 * @author ChenST */ public class EmptyAction implements Action { @Override public String doThing() { return "什么也没加"; } }
/** * 加了苹果汁 * @author ChenST * */ public class AddAppleAction implements Action { @Override public String doThing() { return "加了[苹果汁]"; } }
/** * 咖啡抽象类 * @author ChenST */ public abstract class Coffee { private Action action; public Coffee(Action action){ this.action = action; System.out.println(this.result()); } public Action getAction(){ return action; } /** * 得到的咖啡结果 * @return */ public abstract String result(); }
/** * 大杯咖啡 * @author ChenST */ public class BigCupCoffe extends Coffee { public BigCupCoffe(Action action){ super(action); } @Override public String result() { String thing = this.getAction().doThing(); return "[大杯]"+thing+"的咖啡"; } }
/** * 中杯咖啡 * @author ChenST * */ public class MiddleCupCoffee extends Coffee { public MiddleCupCoffee(Action action){ super(action); } @Override public String result() { String thing = this.getAction().doThing(); return "[中杯]"+thing+"的咖啡"; } }
public class Test { public static void main(String[] args) { //加牛奶的大杯咖啡 Coffee coffee1 = new BigCupCoffe(new AddMilkAction()); //什么也没加的大杯咖啡 Coffee coffee2 = new BigCupCoffe(new EmptyAction()); //加苹果汁的大杯咖啡 Coffee coffee3 = new BigCupCoffe(new AddAppleAction()); //加牛奶的中杯咖啡 Coffee coffee4 = new MiddleCupCoffee(new AddMilkAction()); //什么也没加的中杯咖啡 Coffee coffee5 = new MiddleCupCoffee(new EmptyAction()); //加苹果汁的中杯咖啡 Coffee coffee6 = new MiddleCupCoffee(new AddAppleAction()); } }
[大杯]加了[牛奶]的咖啡 [大杯]什么也没加的咖啡 [大杯]加了[苹果汁]的咖啡 [中杯]加了[牛奶]的咖啡 [中杯]什么也没加的咖啡 [中杯]加了[苹果汁]的咖啡