这是我参与8月更文挑战的第15天,活动详情查看:8月更文挑战
桥接模式
将抽象部分与实现部分分离,使它们都可以独立的变化。
它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。
优点
- 抽象与实现分离,扩展能力强
- 符合开闭原则
- 符合合成复用原则
- 其实现细节对客户透明
缺点
由于聚合关系建立在抽象层,要求开发者针对抽象化进行设计与编程,能正确地识别出系统中两个独立变化的维度,这增加了系统的理解与设计难度。
结构
- 抽象化(Abstraction)角色:定义抽象类,并包含一个对实现化对象的引用。
- 扩展抽象化(Refined Abstraction)角色:是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法。
- 实现化(Implementor)角色:定义实现化角色的接口,供扩展抽象化角色调用。
- 具体实现化(Concrete Implementor)角色:给出实现化角色接口的具体实现。
演示
反例
// 定义衣服制作接口
public interface Clothes {
void make();
}
// 实现类
public class JacketClothes implements Clothes {
@Override
public void make() {
System.out.println("制作上衣!");
}
}
// 添加品牌
public class LiNingClothes extends JacketClothes {
@Override
public void make() {
System.out.println("李宁品牌:制作上衣!");
}
}
public class ErkeClothes extends JacketClothes {
@Override
public void make() {
System.out.println("鸿星尔克品牌:制作上衣!");
}
}
通过上面的代码可以看出,通过继承的方式实现品牌衣服的生产,会存在很严重的问题:
如果存在多个品牌就需要生成多个类,如果一个品牌存在多种衣服分类则也需要生成多个分类
这样就导致我们的代码扩展性很差,且也不符合开闭原则
接下来再看看通过桥接模式实现方式
正例
1、定义品牌维度抽象类
public interface Brand {
void info();
}
2、定义品牌
public class LiNingBrand implements Brand {
@Override
public void info() {
System.out.print("李宁品牌:");
}
}
public class ErkeBrand implements Brand {
@Override
public void info() {
System.out.print("鸿星尔克品牌:");
}
}
3、定义产品抽象类
public abstract class Clothes {
private Brand brand;
public Clothes(Brand brand) {
this.brand = brand;
this.brand.info();
}
protected abstract void make();
}
4、定义产品实现类
public class JacketClothes extends Clothes {
public JacketClothes(Brand brand) {
super(brand);
}
@Override
public void make() {
System.out.println("制作上衣!");
}
}
public class PantsClothes extends Clothes {
public PantsClothes(Brand brand) {
super(brand);
}
@Override
public void make() {
System.out.println("制作裤子!");
}
}
5、客户端
public class Client {
public static void main(String[] args) {
Clothes liNingJacket = new JacketClothes(new LiNingBrand());
liNingJacket.make(); // 李宁品牌:制作上衣!
Clothes erkeJacket = new JacketClothes(new ErkeBrand());
erkeJacket.make(); // 鸿星尔克品牌:制作上衣!
Clothes liNingPants = new PantsClothes(new LiNingBrand());
liNingPants.make(); // 李宁品牌:制作裤子!
Clothes erkePants = new PantsClothes(new ErkeBrand());
erkePants.make(); // 鸿星尔克品牌:制作裤子!
}
}
总结
1、实现了抽象和实现分离,提高了系统的灵活性
2、代替多层继承关系,减少类的数量,提高了系统拓展性
3、满足了单一职责和开闭原则
4、多个维度可独立变化而不影响其他维度