桥接模式(将一个继承关系变为组合关系)
场景:多种手机
现在有三类手机,每种类别的手机有三种不同的品牌,每种手机都有相同的功能(打电话等),现在需要我们创建调用某种手机的call方法
传统实现:
类似工厂模式,先按照手机类别创建三个类,每个类下根据品牌创建具体的手机对象
可以实现功能,但是当类很多时会出现组合爆炸
桥接模式
桥接模式本质是使用合成复用原则将其中的一个继承变为了组合,使得代码的耦合度降低
1
2
3
4public interface Brand { void call(); }
1
2
3
4
5
6
7public class Apple implements Brand{ @Override public void call() { System.out.println("Apple"); } }
1
2
3
4
5
6
7
8
9
10public abstract class Phone { private final Brand brand; Phone(Brand brand){ this.brand=brand; } void call(){ brand.call(); } }
1
2
3
4
5
6
7public class SplitPhone extends Phone{ SplitPhone(Brand brand) { super(brand); System.out.println("SplitPhone"); } }
其中抽象类Phone其实就起到了桥接的作用,通过调用父类的方法间接使用Brand中的方法,这样就可以避免组合爆炸的问题,降低了耦合性。这样增加手机的类型时,只需要实现Phone接口即可
个人思考后改进桥接模式
上述是将一个继承变成了组合而保留了另一个继承关系。但是如果将另一个继承也变成组合,这样设计的耦合度会更低。
也就是将上述的两个特征抽象出来,变为phone的两个属性,这样就可以在构造方法中传入这两个属性
1
2
3
4
5
6
7
8
9
10@AllArgsConstructor public class Phone { Type type; Brand brand; void call(){ brand.call(); type.call(); } }
这样做,无论是增加品牌还是增加类型,这个Phone都不用发生变化,耦合度更低
但是也有它的缺点:灵活性会降低,并且只有所有手机的call方法的流程都是这样才能使用,因而桥接模式实用性更广
使用桥接模式时:
1
2
3
4
5SplitPhone(Brand brand) { super(brand); System.out.println("SplitPhone"); }
可以在方法前后很灵活得进行修改,相当于进行了代理
而全部都使用组合后:
1
2
3
4
5void call(){ brand.call(); type.call(); }
type的方法只能放在前面或者后面,想要实现功能会变得更加复杂,并且可能含义不清晰,不利于我们编写代码。因为继承有衍生的含义而组合代表是这个类的一部分。
小结
桥接模式是将一部分继承关系变为组合关系来降低耦合性,但是不能将所有的继承都变成组合,否则会使得设计模式的适用性降低,如果出现了整个系统都不能兼容添加的这个类的情况,这个系统的根基就会被破坏。因而设计模式要在低耦合和高适用性之间做出权衡。像这种有多个因素决定种类的情况,可以将一个主要因素适用继承实现,其余的次要因素用组合来实现。
桥接模式的作用就是减少继承的个数
最后
以上就是仁爱人生最近收集整理的关于设计模式——桥接模式的全部内容,更多相关设计模式——桥接模式内容请搜索靠谱客的其他文章。
发表评论 取消回复