携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第13天,点击查看活动详情
简介
桥接模式的定义:
桥接模式是将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interfce)模式。
通俗地理解就是避免在两个层次的概念上建立静态的继承关系,而是使用组合的方式来实现,降低这2个可变维度的耦合性。在程序运行时可以动态将一个抽象化子类的对象和一个实现化子类的对象进行组合,即系统需要对抽象化角色和实现化角色进行动态耦合。
桥接模式使用的场景是一个类存在两个(或多个)独立变化的维度,且这两个(或多个)维度都需要独立进行扩展,但是如果一个类存在3个修辞的维度,而且要在3个维度上均及进行拓展,那么它就无能为力了。
案例
先用一个例子来说明需求,我们给电脑定义2个维度,一个是品牌,第二个是电脑类型。比如华为的笔记本、小米的平板等等。那我们每个维度上都有2种类型,品牌维度上有华为和小米,电脑类型上有笔记本电脑和台式机,很显然通过坐标系可以明确看出,我们构建的产品有4种,这个时候我们就要写4个类,分别去继承品牌和电脑类型2个维度的父类或接口。
此时如果需要增加一个维度类型,那我们就要增加2个类。咋一看2个还好,不多,但是如果在某个维度数量多的情况下,那要新增另一个维度,这个数量就想当大了。比如我们新增一个联想的品牌,那我们就要新增联想笔记本,联想台式机,一共3个类。如果使用桥接模式,我们完全可以避免,我们只需新增品牌即可。
定义品牌接口
public interface Brand {
void brandName();
}
有两个品牌华为和小米分别实现它
public class Huawei implements Brand {
@Override
public void brandName() {
System.out.println("huawei");
}
}
public class Xiaomi implements Brand{
@Override
public void brandName() {
System.out.println("xiaomi");
}
}
关键来了,我们定义一个抽象的电脑,然后将品牌的接口组合进去,通过构造方法设定品牌的确定值
public abstract class Computer {
protected Brand brand;
public Computer(Brand brand) {
this.brand = brand;
}
public void brandAndType(){
brand.brandName();
}
}
定义台式机和笔记本分别取继承抽象类Computer,真正的组合在这里实现的,这个类就是桥接模式的桥,虽然它是桥梁,但是因为它本身是继承了Computer的,所以这个桥自带了一个属性,然后通过构造方法注入品牌,将产品的两个维度组合在一起完成产品的描述和定义。
public class Desktop extends Computer {
public Desktop(Brand brand) {
super(brand);
}
@Override
public void brandAndType() {
super.brandAndType();
System.out.println("desktop");
}
}
public class Laptop extends Computer {
public Laptop(Brand brand) {
super(brand);
}
@Override
public void brandAndType() {
super.brandAndType();
System.out.println("laptop");
}
}
测试类
public class App {
public static void main(String[] args) {
Desktop desktop = new Desktop(new Huawei());
desktop.brandAndType();
Laptop laptop = new Laptop(new Xiaomi());
laptop.brandAndType();
}
}
输出结果
总结
- 抽象与实现分离,扩展能力强,从而极大的提供了系统的灵活性,这有助于系统进行分层设计,从而产生更好的结构化系统。
- 桥接模式提代了多层继承方案,可以减少子类的个数,降低系统的管理和维护成本
- 桥接模式提高了系统的可扩展性,在两个变化维度中任意扩展一个维度,都只需要进行简单拓展,符合开闭原则