简介
桥接模式:将实现和抽象放在不同的类层次中,是两个层次可以独立改变,是一种结构型设计模式。基于类的最小设计原则。通过使用封装、聚合及继承等行为让不同的类承担不同的职责。它的主要特点是把抽象(Abstraction)与行为实现 (Implementation)分离开来,从而可以保持各部分的独立性以及应对他们的功能扩展。
小demo
需求:现在对不同手机类型的不同品牌实现操作编程(比如: 打电话等)
不适用桥接模式实现
- 定义手机基类
public abstract class Phone {
public abstract void call();
}
- 定义手机样式
public class Folded extends Phone {
@Override
public void call() {
System.out.print("折叠样式");
}
}
- 定义手机品牌
public class FoldedXiaomi extends Folded {
@Override
public void call() {
super.call();
System.out.println("小米手机打电话");
}
}
- 测试
public class Client {
public static void main(String[] args) {
FoldedXiaomi xiaomi = new FoldedXiaomi();
xiaomi.call();
}
}
// 输出:折叠样式小米手机打电话
当我们要新加属性时
- 新加手机样式
public class UpRight extends Phone {
@Override
public void call() {
System.out.println("直屏样式");
}
}
- 新加手机
public class UpRightXiaomi extends UpRight {
@Override
public void call() {
super.call();
System.out.println("小米手机打电话");
}
}
针对上述代码所存在的问题
- 扩展性问题(类爆炸),如果我们再增加手机的样式(直屏样式),就需要增加各个品牌手机的类,同样如果我们增加一个手机品牌,也要在各个手机样式类下增加。
- 违反了单一职责原则,当我们增加手机样式时,要同时增加所有品牌的手机,这样增加了代码维护成本.
怎对上述问题可用桥接方法解决
- 创建品牌接口 Brand
// 品牌
public interface Brand {
void open();
void close();
void call();
}
- 创建手机品牌
public class XiaoMi implements Brand {
@Override
public void open() {
System.out.println("小米开机");
}
@Override
public void close() {
System.out.println("小米关机");
}
@Override
public void call() {
System.out.println("小米打电话");
}
}
- 创建手机抽象类
public abstract class Phone {
Brand brand;
public Phone(Brand brand) {
this.brand = brand;
}
protected void open() {
this.brand.open();
}
protected void close() {
brand.close();
}
protected void call() {
brand.call();
}
}
- 创建手机类型
public class FoldedPhone extends Phone {
public FoldedPhone(Brand brand) {
super(brand);
}
public void open() {
super.open();
System.out.println(" 折叠样式手机 ");
}
public void close() {
super.close();
System.out.println(" 折叠样式手机 ");
}
public void call() {
super.call();
System.out.println(" 折叠样式手机 ");
}
}
- 测试
public static void main(String[] args) {
FoldedPhone phone = new FoldedPhone(new XiaoMi());
phone.open();
phone.call();
phone.close();
}
输出:
假如我们需要新增加一个手机样式,只需要做如下修改:
- 增加一个样式
public class UpRightPhone extends Phone {
//构造器
public UpRightPhone(Brand brand) {
super(brand);
}
public void open() {
super.open();
System.out.println(" 直立样式手机 ");
}
public void close() {
super.close();
System.out.println(" 直立样式手机 ");
}
public void call() {
super.call();
System.out.println(" 直立样式手机 ");
}
}
只需一步,我们就完成样式的添加,不在需要向样式下面添加手机类型。
桥接模式的注意事项和细节
- 实现了抽象和实现部分的分离,从而极大的提供了系统的灵活性,让抽象部分和实现部分独立开来,这有助于系统进行分层设计,从而产生更好的结构化系统。
- 对于系统的高层部分,只需要知道抽象部分和实现部分的接口就可以了,其它的部分由具体业务来完成。
- 桥接模式替代多层继承方案,可以减少子类的个数,降低系统的管理和维护成本。
- 桥接模式的引入增加了系统的理解和设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计和编程
- 桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围有一定的局 限性,即需要有这样的应用场景