桥接模式(Bridge Pattern): 属于结构形设计模式,通过提供抽象化和实例化之间的桥接结构,来实现二者的解耦。把抽象(abstraction) 与行为实现(implementation)分离开来,从而可以保持各部分的独立性以及应对它们的功能扩展。
这种模式涉及到一个作为桥接的接口,使得实体类的功能独立于接口实现类。这两种类型的类可被结构化改变而互不影响。
使用场景
一个甜品店,售卖的食品有蛋糕、奶茶和牛奶,但是每个食品又有多种口味:草莓味、芒果味和香蕉味,如下图
上图显示了多继承的关系并且对于每个食品都有多种口味,当我们新增加一个食品,又在下面有多种口味继承,显得非常不灵活。所以,此时我们就可以通过桥接模式来优化这种多继承的情况。在食品与口味之间用桥接模式来建立一种连接,而不再使用上面的继承关系。如下图所示:
实现
我们有一个作为桥接实现的 Fruit 接口和实现了 Fruuit 接口的实体类 Banana、Strawberry和Mango。食品类 Food 是一个抽象类,该类包含一个 Fruit 的对象和一个 add 方法。食品 Food 的子类 Cake、Milk和milkTea 继承自 Food,并重写 add 方法。 BridgePatternDemo 类使用 Food 类来获取到不同食品的不同口味(比如:面包可以有3种口味,牛奶可以有3种可谓)。
步骤1:创建桥接实现接口 Fruit
//TODO 桥接接口
public interface Fruit{
public void beAdd(String food);
}
步骤2:创建实现了 Fruit 接口的实体桥接实现类
public class Banana implements Fruit{
@Override
public void beAdd(String food){
System.out.println("香蕉味的" + food);
}
}
public class StrawBerry implements Fruit{
@Override
public void beAdd(String food){
System.out.println("草莓味的" + food);
}
}
public class Mango implements Fruit{
@Override
public void beAdd(String food){
System.out.println("芒果味的" + food);
}
}
步骤3:创建 Food 抽象类,并使用 Fruit 接口
public abstract class Food{
// Fruit 接口类型的成员变量
protected Fruit fruit;
// 传入一个 fruit 对象
public setFood(Fruit fruit){
this.fruit= fruit; // 聚合
}
public abstract void add();
}
步骤4:创建实现了 Food 抽象类的实体类 Cake、Milk、Milktea
public class Cake extends Food{
@Override
public void add(){
fruit.beAdd("蛋糕");
}
}
public class Milk extends Food{
@Override
public void add(){
fruit.beAdd("牛奶");
}
}
public class Milktea extends Food{
@Override
public void add(){
fruit.beAdd("奶茶");
}
}
步骤5:打印出不同口味的食品
public class BridgePatternDemo{
public static void main(String[] args){
// 三种水果口味
Fruit banana = new Banana();
Fruit mango = new Mango();
Fruit strawberry = new Strawberry()
//蛋糕
Food cake = new Cake();
cake.setFood(banana); // 香蕉味蛋糕
cake.add();
cake.setFood(mango);// 芒果味蛋糕
cake.add();
cake.setFood(strawberry);// 草莓味蛋糕
cake.add();
//多口味的牛奶、奶茶
//...
}
步骤6:输出结果
香蕉味的蛋糕
芒果味的蛋糕
草莓味的蛋糕
优缺点
优点:
桥接模式可以取代多继承的方案。多继承违背了单一职责原则,复用性交较差,类的个数也非常多。桥接模式可以极大的减少子类的个数,从而降低管理合维护的成本。
桥接模式极大的提高了系统可扩展性,在两个变化维度种任意扩展一个维度,都不需要修改原有的系统,符合开闭原则。
缺点:
会增加系统的理解与设计难度,由于关联关系建立在抽象层,要求开发者一开始就针对抽象层进行设计与编程。