阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

桥接

105次阅读
没有评论

共计 2373 个字符,预计需要花费 6 分钟才能阅读完成。

将抽象部分与它的实现部分分离,使它们都可以独立地变化。

桥接模式的定义非常玄乎,直接理解不太容易,所以我们还是举例子。

假设某个汽车厂商生产三种品牌的汽车:Big、Tiny 和 Boss,每种品牌又可以选择燃油、纯电和混合动力。如果用传统的继承来表示各个最终车型,一共有 3 个抽象类加 9 个最终子类:

┌───────┐
│ Car │
└───────┘
┌──────────────────┼───────────────────┐
│ │ │
┌───────┐ ┌───────┐ ┌───────┐
│BigCar │ │TinyCar│ │BossCar│
└───────┘ └───────┘ └───────┘
▲ ▲ ▲
│ │ │
│ ┌───────────────┐│ ┌───────────────┐│ ┌───────────────┐
├─│ BigFuelCar │├─│ TinyFuelCar │├─│ BossFuelCar │
│ └───────────────┘│ └───────────────┘│ └───────────────┘
│ ┌───────────────┐│ ┌───────────────┐│ ┌───────────────┐
├─│BigElectricCar │├─│TinyElectricCar│├─│BossElectricCar│
│ └───────────────┘│ └───────────────┘│ └───────────────┘
│ ┌───────────────┐│ ┌───────────────┐│ ┌───────────────┐
└─│ BigHybridCar │└─│ TinyHybridCar │└─│ BossHybridCar │
└───────────────┘ └───────────────┘ └───────────────┘

如果要新增一个品牌,或者加一个新的引擎(比如核动力),那么子类的数量增长更快。

所以,桥接模式就是为了避免直接继承带来的子类爆炸。

我们来看看桥接模式如何解决上述问题。

在桥接模式中,首先把 Car 按品牌进行子类化,但是,每个品牌选择什么发动机,不再使用子类扩充,而是通过一个抽象的“修正”类,以组合的形式引入。我们来看看具体的实现。

首先定义抽象类Car,它引用一个Engine

public abstract class Car {// 引用 Engine:
protected Engine engine;
public Car(Engine engine) {this.engine = engine;
}
public abstract void drive();
}

Engine的定义如下:

public interface Engine {void start();
}

紧接着,在一个“修正”的抽象类 RefinedCar 中定义一些额外操作:

public abstract class RefinedCar extends Car {public RefinedCar(Engine engine) {super(engine);
}
public void drive() {this.engine.start();
System.out.println("Drive" + getBrand() + "car...");
}
public abstract String getBrand();
}

这样一来,最终的不同品牌继承自RefinedCar,例如BossCar

public class BossCar extends RefinedCar {public BossCar(Engine engine) {super(engine);
}
public String getBrand() {return "Boss";
}
}

而针对每一种引擎,继承自Engine,例如HybridEngine

public class HybridEngine implements Engine {public void start() {System.out.println("Start Hybrid Engine...");
}
}

客户端通过自己选择一个品牌,再配合一种引擎,得到最终的 Car:

RefinedCar car = new BossCar(new HybridEngine());
car.drive();

使用桥接模式的好处在于,如果要增加一种引擎,只需要针对 Engine 派生一个新的子类,如果要增加一个品牌,只需要针对 RefinedCar 派生一个子类,任何 RefinedCar 的子类都可以和任何一种 Engine 自由组合,即一辆汽车的两个维度:品牌和引擎都可以独立地变化。

┌───────────┐
│ Car │
└───────────┘
┌───────────┐ ┌─────────┐
│RefinedCar │ ─ ─ ─▶│ Engine │
└───────────┘ └─────────┘
▲ ▲
┌────────┼────────┐ │ ┌──────────────┐
│ │ │ ├─│ FuelEngine │
┌───────┐┌───────┐┌───────┐ │ └──────────────┘
│BigCar ││TinyCar││BossCar│ │ ┌──────────────┐
└───────┘└───────┘└───────┘ ├─│ElectricEngine│
│ └──────────────┘
│ ┌──────────────┐
└─│ HybridEngine │
└──────────────┘

桥接模式实现比较复杂,实际应用也非常少,但它提供的设计思想值得借鉴,即不要过度使用继承,而是优先拆分某些部件,使用组合的方式来扩展功能。

练习

使用桥接模式扩展一种新的品牌和新的核动力引擎。

下载练习

小结

桥接模式通过分离一个抽象接口和它的实现部分,使得设计可以按两个维度独立扩展。

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2024-08-05发表,共计2373字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中