共计 2408 个字符,预计需要花费 7 分钟才能阅读完成。
一 引言
桥接模式了解起来也是非常简单,咱们依然从生存中的问题登程,如果一些事物的分类能够从两个或者多个维度来划分,就比方不同品牌和不同排量的汽车,他们能够有 M x N 种后果(例如:奥迪 A8 2.0 排量,奥迪 A6 2.0 排量,飞驰 S350L 3.0 排量,等等)
这种状况下如果抉择继承的形式,就会呈现一种多层继承的关系,子类就会十分多,同时扩大也很麻烦
像这样的例子还有很多,比方品牌和产品类型之间,或者不同色彩和字体的图形或者文字,等等
二 桥接模式引入
还是老规矩,间接用理论的代码例子引入
背景:相机品牌(索尼,佳能等)和相机类型(单反,微单,卡片机等)两种维族的组合后果
咱们想要做的就是勾销他们的继承关系,而应用组合
- 先创立一个形象的相机品牌类
/**
* 相机品牌类
*/
public interface CameraBrand {void showInfo();
}
- 接着就是两个具体的实现类,这里举了索尼和佳能两个品牌
/**
* 索尼品牌
*/
public class Sony implements CameraBrand {
@Override
public void showInfo() {System.out.print("【索尼】");
}
}
/**
* 佳能品牌
*/
public class Canon implements CameraBrand {
@Override
public void showInfo() {System.out.print("【佳能】");
}
}
- 上面再将相机产品类形象进去,为了实现组合,引入相机品牌成员,为了能让在子类中也能拜访到,我用了 protected
/**
* 形象相机类
*/
public abstract class Camera {
// 将品牌组合进来
protected CameraBrand cameraBrand;
public Camera(CameraBrand cameraBrand) {this.cameraBrand = cameraBrand;}
public void showInfo(){cameraBrand.showInfo();
}
}
- 上面就是两个相机的产品具体类型
/**
* 单反相机
*/
public class SlrCameras extends Camera {public SlrCameras(CameraBrand cameraBrand) {super(cameraBrand);
}
@Override
public void showInfo() {super.showInfo();
System.out.println("单反相机");
}
}
/**
* 卡片相机(数字相机)*/
public class DigitalCamera extends Camera {public DigitalCamera(CameraBrand cameraBrand) {super(cameraBrand);
}
@Override
public void showInfo() {super.showInfo();
System.out.println("卡片相机(数字相机)");
}
}
测试一下
public class Test {public static void main(String[] args) {
// 索尼单反相机
Camera camera = new SlrCameras(new Sony());
camera.showInfo();
// 佳能卡片相机
Camera camera2 = new DigitalCamera(new Canon());
camera2.showInfo();}
}
运行后果:
【索尼】单反相机
【佳能】卡片相机(数字相机)
从上述代码中能够看出,咱们当初曾经能够对不同类型和不同产品的相机进行任意的组合了,例如索尼单反相机,或者佳能单反相机都是能够的,如果想要减少一个品牌或者产品只须要减少具体的实现类就能够了
三 桥接模式实践
(一) 定义和特点
定义:将形象与实现拆散,使它们能够独立变动
实现的意思并不是指形象的派生类,而是指通过组合来代替继承关系,从而升高形象和具体实现产品两个可变换维度之间的耦合,就像咱们的相机品牌和相机产品类型之间的拆散
(二) 构造
简略阐明一下其中的角色
-
实现化角色(Implementor):定义实现化角色的接口,供扩大抽象化角色应用
- 例如形象出相机的品牌,能够扩大出例如佳能索尼等各种品牌
-
具体实现化角色(ConcreteImplementor):实现化角色的具体实现
- 例如各种品牌
-
抽象化(Abstraction)角色 :定义一个抽象类,其中援用了实现化角色(想要组合)
- 例如相机产品
-
扩大抽象化(RefinedAbstraction)角色 :抽象化角色子类,实现父类办法,且通过组合关系调用实现化角色中的业务办法
- 例如具体相机产品,单反相机,卡片相机等等
(三) 长处和毛病
长处:
常常遇到一些能够通过两个或多个维度划分的事物,第一种解决形式就是多层继承,然而复用性比拟差,同时类的个数也会很多,桥接模式是改良其的更好方法
桥接模式加强了零碎的扩展性,在两个维度中扩大任意一个维度都不须要批改原有代码,合乎开闭准则
毛病:
桥接模式减少了零碎的了解与设计难度:因为聚合关系建设在形象层,要求开发者针对抽象化进行设计与编程,能正确地辨认出零碎中两个独立变动的维度
(四) 应用场景
-
一个零碎须要在构建的抽象化角色和具体化角色之间减少更多的灵活性,防止在两个档次之间建设动态的继承分割,通过桥接模式能够使它们在形象层建设一个关联关系。
- 抽象化角色和实现化角色能够以继承的形式独立扩大而互不影响,在程序运行时能够动静将一个抽象化子类的对象和一个实现化子类的对象进行组合,即零碎须要对抽象化角色和实现化角色进行动静耦合
- 一个类存在两个独立变动的维度,且这两个维度都须要进行扩大
- 尽管在零碎中应用继承是没有问题的,然而因为抽象化角色和具体化角色须要独立变动,设计要求须要独立治理这两者
- 不心愿应用继承或因为多层次继承导致系统类的个数急剧减少的零碎