Design Patterns(六) Bridge
The bridge pattern applies when there is a need to avoid permanent binding between an abstraction and an implementation and when the abstraction and implementation need to vary independently. Using the bridge pattern would leave the client code unchanged with no need to recompile the code.
前言 桥接模式,又叫桥梁模式,顾名思义,就是有座“桥”,那这座桥是什么呢?就是一条聚合线(下方UML图),比如我们下面会举的例子,手机有手机品牌和手机游戏等等,每个手机品牌都有多款游戏,那是不是二者之间就是聚合关系了,这是合成/聚合复用原则的体现,当我们发现类有多层继承时就可以考虑使用桥接模式,用聚合代替继承。 桥接模式(Bridge),将抽象部分与它的实现部分分离,使它们都可以独立地变化。
桥接模式 角色:
1) 桥接模式(Bridge模式)是指:将 实现与 抽象放在两个不同的类层次中,使两个层次可以独立改变; 2) 是一种结构型设计模式; 3) Bridge模式基于 类的最小设计原则,通过使用封装、聚合及继承等行为让不同的类承担不同的职责。它的主要特点是把抽象(Abstraction)与行为实现(Implementation)分离开来,从而可以保持各部分的独立性以及应对他们的功能扩展。
桥接模式-UML图:
桥接模式-案例图:
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 public class Bridge { public static void main (String[] args) { System.out.println("========Android FoldPhone========" ); Phone phone1 = new FoldPhone(new Android()); phone1.open(); phone1.call(); phone1.close(); System.out.println("========Android UprightPhone========" ); Phone phone2 = new UprightPhone(new Android()); phone2.open(); phone2.call(); phone2.close(); System.out.println("========Android SlidePhone========" ); Phone phone3 = new SlidePhone(new Android()); phone3.open(); phone3.call(); phone3.close(); System.out.println("========Apple FoldPhone========" ); Phone phone4 = new FoldPhone(new Apple()); phone4.open(); phone4.call(); phone4.close(); System.out.println("========Apple UprightPhone========" ); Phone phone5 = new UprightPhone(new Apple()); phone5.open(); phone5.call(); phone5.close(); System.out.println("========Apple SlidePhone========" ); Phone phone6 = new SlidePhone(new Apple()); phone6.open(); phone6.call(); phone6.close(); System.out.println("========Apple Nokia========" ); Phone phone7 = new FoldPhone(new Nokia()); phone7.open(); phone7.call(); phone7.close(); System.out.println("========Nokia UprightPhone========" ); Phone phone8 = new UprightPhone(new Nokia()); phone8.open(); phone8.call(); phone8.close(); System.out.println("========Nokia SlidePhone========" ); Phone phone9 = new SlidePhone(new Nokia()); phone9.open(); phone9.call(); phone9.close(); } } interface Brand { void open () ; void close () ; void call () ; } class Android implements Brand { @Override public void open () { System.out.println("安卓手机开机了" ); } @Override public void close () { System.out.println("安卓手机关机了" ); } @Override public void call () { System.out.println("安卓手机打电话了" ); } } class Apple implements Brand { @Override public void open () { System.out.println("苹果手机开机了" ); } @Override public void close () { System.out.println("苹果手机关机了" ); } @Override public void call () { System.out.println("苹果手机打电话了" ); } } class Nokia implements Brand { @Override public void open () { System.out.println("诺基亚手机开机了" ); } @Override public void close () { System.out.println("诺基亚手机关机了" ); } @Override public void call () { System.out.println("诺基亚手机打电话了" ); } } abstract class Phone { Brand brand; Phone(Brand brand) { this .brand = brand; } void open () { brand.open(); } void close () { brand.close(); } void call () { brand.call(); } } class FoldPhone extends Phone { FoldPhone(Brand brand) { super (brand); } @Override void open () { System.out.print("折叠的 " ); super .open(); } @Override void close () { System.out.print("折叠的 " ); super .close(); } @Override void call () { System.out.print("折叠的 " ); super .call(); } } class UprightPhone extends Phone { UprightPhone(Brand brand) { super (brand); } @Override void open () { System.out.print("直立的 " ); super .open(); } @Override void close () { System.out.print("直立的 " ); super .close(); } @Override void call () { System.out.print("直立的 " ); super .call(); } } class SlidePhone extends Phone { SlidePhone(Brand brand) { super (brand); } @Override void open () { System.out.print("滑盖的 " ); super .open(); } @Override void close () { System.out.print("滑盖的 " ); super .close(); } @Override void call () { System.out.print("滑盖的 " ); super .call(); } }
总结 桥接模式的注意事项和细节:
1) 实现了抽象和实现部分的分离,从而极大的提供了系统的灵活性,让抽象部分和实现部分独立开来,这有助于系统进行分层设计,从而产生更好的结构化系统; 2) 对于系统的高层部分,只需要知道抽象部分和实现部分的接口就可以了,其它的部分由具体业务来完成; 3) 桥接模式替代多层继承方案,可以减少子类的个数,降低系统的管理和维护成本; 4) 桥接模式的引入增加了系统的理解和设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计和编程; 5) 桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围有一定的局限性,即需要有这样的应用场景。
桥接模式其它应用场景:
1) 对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用; 2) 常见的应用场景: -JDBC驱动程序 -银行转账系统 转账分类: 网上转账,柜台转账,AMT转账 转账用户类型:普通用户,银卡用户,金卡用户.. -消息管理 消息类型:即时消息,延时消息 消息分类:手机短信,邮件消息,QQ消息…
延伸 桥接模式 Bridge Design Pattern 23种设计模式之桥接模式 桥梁模式(Bridge Pattern) 桥接模式-Bridge Pattern 尚硅谷Java设计模式,韩顺平图解java设计模式
<
Design Patterns(七) Decorator
Design Patterns(五) Adapter
>