桥接模式及其应用

2022-06-21  本文已影响0人  文景大大

一、模式介绍

桥接模式可以将抽象部分和具体实现部分进行分离,使他们都可以独立地变化。它存在的主要目的是通过组合的方式建立两个/多个维度类之间的关系,替代通过继承的方式,实现多重继承的效果。多重继承违背了单一职责原则,复用性及扩展性较差,桥接模式可以作为多重继承方案很好的替代。

需要注意,此处的抽象部分和具体实现部分并非指面向对象设计中的高层和低层的关系,而是指一个事物的两种独立变化的维度,其中抽象包含对具体实现的引用,以此来实现桥接。一般桥接模式会包含如下四种角色:

因此,如果一个业务场景如果满足如下的特点,就可以考虑使用桥接模式来实现:

我们来看一个实际的案例,去咖啡店买咖啡有多种套餐,分析下来,咖啡有两个维度:

很明显,这是两个独立变化的维度,我们使用桥接模式来实现咖啡的套餐。

public abstract class Coffee {
    /**
     * 保持对实现化角色接口的引用,实现桥接
     */
    protected ICoffeeAdditives additives;

    public Coffee(ICoffeeAdditives additives) {
        this.additives = additives;
    }

    /**
     * 定义公共行为
     * @param num
     */
    public abstract void orderCoffee(int num);
}
@Slf4j
public class RefineCoffee extends Coffee{
    public RefineCoffee(ICoffeeAdditives additives) {
        super(additives);
    }

    @Override
    public void orderCoffee(int num) {
        log.info("{}杯咖啡!", num);
    }

    /**
     * 增强行为
     */
    public void sayHello(){
        log.info("谢谢惠顾!");
    }
}
@Slf4j
public class MiddleCoffee extends RefineCoffee{
    public MiddleCoffee(ICoffeeAdditives additives) {
        super(additives);
    }

    @Override
    public void orderCoffee(int num) {
        log.info("中杯!");
        super.orderCoffee(num);
        // 桥接另外一个维度的行为
        additives.addSomething();
    }
}
public interface ICoffeeAdditives {
    /**
     * 定义实现化角色的通用行为
     */
    void addSomething();
}
@Slf4j
public class MilkAdditives implements ICoffeeAdditives{
    @Override
    public void addSomething() {
        log.info("添加牛奶!");
    }
}
@Slf4j
public class JuiceAdditives implements ICoffeeAdditives{
    @Override
    public void addSomething() {
        log.info("添加果汁!");
    }
}
public class Main {
    public static void main(String[] args) {
        RefineCoffee coffee = new MiddleCoffee(new MilkAdditives());
        coffee.orderCoffee(2);
        coffee.sayHello();
    }
}

如此,杯体大小和添加物两个维度无论再怎么扩展,只要增加对应的扩展类即可,无需修改已有的内容,符合开闭原则。

二、使用案例

三、模式总结

3.1 优点

3.2 缺点

上一篇下一篇

猜你喜欢

热点阅读