1. 背景
下面是一些官方的说明,比较晦涩,必须等你有一定的经验后才能理解: 1. 如果一个系统需要在抽象化和具体化之间增加更多的灵活性,避免在两个层次之间建立静态的继承关系,通过桥接模式可以使它们在抽象层建立一个关联关系。
“抽象部分”和“实现部分”可以以继承的方式独立扩展而互不影响,在程序运行时可以动态将一个抽象化子类的对象和一个实现化子类的对象进行组合,即系统需要对抽象化角色和实现化角色进行动态耦合。
一个类存在两个(或多个)独立变化的维度,且这两个(或多个)维度都需要独立进行扩展。
对于那些不希望使用继承或因为多层继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。
桥梁模式所涉及的角色有:
- 抽象化(Abstraction)角色:抽象化给出的定义,并保存一个对实现化对象的引用。
- 修正抽象化(RefinedAbstraction)角色:扩展抽象化角色,改变和修正父类对抽象化的定义。
- 实现化(Implementor)角色:这个角色给出实现化角色的接口,但不给出具体的实现。必须指出的是,这个接口不一定和抽象化角色的接口定义相同,实际上,这两个接口可以非常不一样。实现化角色应当只给出底层操作,而抽象化角色应当只给出基于底层操作的更高一层的操作。
- 具体实现化(ConcreteImplementor)角色:这个角色给出实现化角色接口的具体实现。
2. 实现
其实通俗的说,如何将两个接口的实现融为一体;
假设现在有个需求,需要做一杯咖啡,咖啡的口味可以选择加糖,加奶,但是咖啡呢,还有个需求,可以选择大杯和小杯;
类似于上面这种需求,需要定义多个接口实现,且需要融为一体,那么,可以实现桥接模式,现在我们选择以选择杯型为主实现,加料为辅;
2.1 定义咖啡抽象类
加奶或者加糖接口ICoffeeAdditives ,通过构造器传入
public abstract class Coffee {
protected ICoffeeAdditives additives;
public Coffee(ICoffeeAdditives additives){
this.additives=additives;
}
public abstract void orderCoffee(int count);
}
2.2 继承咖啡抽象类
public abstract class RefinedCoffee extends Coffee {
public RefinedCoffee(ICoffeeAdditives additives) {
super(additives);
}
public void checkQuality(){
Random ran=new Random();
System.out.println(String.format("%s 添加%s",additives.getClass().getSimpleName(),ran.nextBoolean()?"太多":"正常"));
}
}
2.3 定义实现类-大杯
/**
* 大杯咖啡
*
* @author wql
* @date 2022/3/27 18:02
*/
public class LargeCoffee extends RefinedCoffee {
@Override
public void orderCoffee(int count) {
}
public LargeCoffee(ICoffeeAdditives additives) {
super(additives);
}
@Override
public void checkQuality() {
super.checkQuality();
}
}
2.4 定义加料的接口
public interface ICoffeeAdditives {
void addSomething();
}
2.5 定义加料的接口实现-加糖
public class Sugar implements ICoffeeAdditives {
@Override
public void addSomething() {
System.out.println("加糖");
}
}
2.6 定义加料的接口实现-加奶
public class Milk implements ICoffeeAdditives {
@Override
public void addSomething() {
System.out.println("加奶");
}
}
2.7 测试
/**
* 测试桥接模式
*
* @author wql
* @date 2022/3/27 18:01
*/
public class TestBridgePattern {
public static void main(String[] args) {
//点两杯加奶的大杯咖啡
RefinedCoffee largeWithMilk=new LargeCoffee(new Milk());
largeWithMilk.orderCoffee(2);
largeWithMilk.checkQuality();
}
}