**
设计模式(六)之桥接模式
**
- 案例说明
我们要品尝一种水果,假设有六种水果:红色苹果、绿色苹果、红色葡萄、绿色葡萄、红枣、青枣,传统写法就要有六个实体类,一旦我们要增加一种水果的颜色或者一个水果的种类,那相对应的实体类就会增加很多,也就会产生我们所说的“类爆炸”问题,我们先来看看传统的写法:
- 不用桥接模式的传统写法
抽象的水果类
public abstract class Fruit {
public abstract void taste();
}
具体的水果类
public class RedApple extends Fruit{
@Override
public void taste() {
System.out.println("红苹果尝起来很甜");
}
}
public class GreenApple extends Fruit{
@Override
public void taste() {
System.out.println("绿苹果尝起来有点酸");
}
}
public class RedDate extends Fruit{
@Override
public void taste() {
System.out.println("红枣尝起来很甜");
}
}
public class GreenDate extends Fruit{
@Override
public void taste() {
System.out.println("青枣尝起来很涩");
}
}
public class RedGrape extends Fruit{
@Override
public void taste() {
System.out.println("红葡萄尝起来很甜");
}
}
public class GreenGrape extends Fruit{
@Override
public void taste() {
System.out.println("绿葡萄尝起来有点酸");
}
}
客户端
public class Client {
public static void main(String[] args) {
Fruit fruit = null;
fruit = new RedApple();
fruit.taste();
fruit = new GreenGrape();
fruit.taste();
}
}
测试
D:\jdk8\bin\java.exe "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2019.2\lib\idea_rt.jar=55367:C:\Program Files\JetBrains\IntelliJ IDEA 2019.2\bin" -Dfile.encoding=UTF-8 -classpath D:\jdk8\jre\lib\charsets.jar;D:\jdk8\jre\lib\deploy.jar;D:\jdk8\jre\lib\ext\access-bridge-64.jar;D:\jdk8\jre\lib\ext\cldrdata.jar;D:\jdk8\jre\lib\ext\dnsns.jar;D:\jdk8\jre\lib\ext\jaccess.jar;D:\jdk8\jre\lib\ext\jfxrt.jar;D:\jdk8\jre\lib\ext\localedata.jar;D:\jdk8\jre\lib\ext\nashorn.jar;D:\jdk8\jre\lib\ext\sunec.jar;D:\jdk8\jre\lib\ext\sunjce_provider.jar;D:\jdk8\jre\lib\ext\sunmscapi.jar;D:\jdk8\jre\lib\ext\sunpkcs11.jar;D:\jdk8\jre\lib\ext\zipfs.jar;D:\jdk8\jre\lib\javaws.jar;D:\jdk8\jre\lib\jce.jar;D:\jdk8\jre\lib\jfr.jar;D:\jdk8\jre\lib\jfxswt.jar;D:\jdk8\jre\lib\jsse.jar;D:\jdk8\jre\lib\management-agent.jar;D:\jdk8\jre\lib\plugin.jar;D:\jdk8\jre\lib\resources.jar;D:\jdk8\jre\lib\rt.jar;D:\ideaworkspace\design_pattern\design\target\classes;D:\dev_tools\repository\org\projectlombok\lombok\1.16.10\lombok-1.16.10.jar com.wd.bridge.none.Client
红苹果尝起来很甜
绿葡萄尝起来有点酸
Process finished with exit code 0
-
桥接模式
我们在传统写法的基础上,加上一个水果种类的接口,具体的水果实现这个接口,将具体水果的颜色属性抽离出来,颜色属性继承水果的抽象类,将水果种类聚合到水果抽象类中,这样不管新增一种颜色或者新增一个水果种类,都只用新增一个类就行了。
水果种类接口
public interface FruitType {
public void taste();
}
具体的水果类,不带水果的颜色属性
public class Apple implements FruitType {
@Override
public void taste() {
System.out.println("苹果很好吃");
}
}
public class ChineseDate implements FruitType {
@Override
public void taste() {
System.out.println("枣很好吃");
}
}
public class Grape implements FruitType{
@Override
public void taste() {
System.out.println("葡萄很好吃");
}
}
抽象的水果类,将水果类型聚合进来了,起到桥接水果类型和水果颜色属性的作用。
public abstract class Fruit {
private FruitType fruitType = null;
public Fruit(FruitType fruitType){
this.fruitType = fruitType;
}
public void taste() {
this.fruitType.taste();
}
}
具体的水果颜色子类
public class RedFruit extends Fruit{
public RedFruit(FruitType fruitType) {
super(fruitType);
}
@Override
public void taste() {
super.taste();
System.out.println("红色水果");
}
}
public class GreenFruit extends Fruit{
public GreenFruit(FruitType fruitType){
super(fruitType);
}
@Override
public void taste() {
super.taste();
System.out.println("绿色水果");
}
}
在客户端定义水果的种类和颜色
public class Client {
public static void main(String[] args) {
Fruit fruit = null;
FruitType fruitType = null;
// 定义水果种类
fruitType = new Grape();
// 定义水果颜色
fruit = new GreenFruit(fruitType);
fruit.taste();
}
}
测试
D:\jdk8\bin\java.exe "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2019.2\lib\idea_rt.jar=55616:C:\Program Files\JetBrains\IntelliJ IDEA 2019.2\bin" -Dfile.encoding=UTF-8 -classpath D:\jdk8\jre\lib\charsets.jar;D:\jdk8\jre\lib\deploy.jar;D:\jdk8\jre\lib\ext\access-bridge-64.jar;D:\jdk8\jre\lib\ext\cldrdata.jar;D:\jdk8\jre\lib\ext\dnsns.jar;D:\jdk8\jre\lib\ext\jaccess.jar;D:\jdk8\jre\lib\ext\jfxrt.jar;D:\jdk8\jre\lib\ext\localedata.jar;D:\jdk8\jre\lib\ext\nashorn.jar;D:\jdk8\jre\lib\ext\sunec.jar;D:\jdk8\jre\lib\ext\sunjce_provider.jar;D:\jdk8\jre\lib\ext\sunmscapi.jar;D:\jdk8\jre\lib\ext\sunpkcs11.jar;D:\jdk8\jre\lib\ext\zipfs.jar;D:\jdk8\jre\lib\javaws.jar;D:\jdk8\jre\lib\jce.jar;D:\jdk8\jre\lib\jfr.jar;D:\jdk8\jre\lib\jfxswt.jar;D:\jdk8\jre\lib\jsse.jar;D:\jdk8\jre\lib\management-agent.jar;D:\jdk8\jre\lib\plugin.jar;D:\jdk8\jre\lib\resources.jar;D:\jdk8\jre\lib\rt.jar;D:\ideaworkspace\design_pattern\design\target\classes;D:\dev_tools\repository\org\projectlombok\lombok\1.16.10\lombok-1.16.10.jar com.wd.bridge.one.Client
葡萄很好吃
绿色水果
Process finished with exit code 0
- 总结
1) 实现了抽象和实现部分的分离,从而极大的提供了系统的灵活性,让抽象部分和实现部分独立开来,这有助于系统进行分层设计,从而产生更好的结构化系统。
2) 对于系统的高层部分,只需要知道抽象部分和实现部分的接口就可以了,其它的部分由具体业务来完成。
3) 桥接模式替代多层继承方案,可以减少子类的个数,降低系统的管理和维护成本。
4) 桥接模式的引入增加了系统的理解和设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计和编程
5) 桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围有一定的局限性,需要有这样的应用场景才能使用。