设计模式之桥接模式

1 定义

桥接模式将抽象部分与它的实现部分分离,使它们可以独立地变化。或者也可以定义为:一个类存在两个(或多个)独立变化的维度,我们可以通过组合的方式,让这两个(或多个)维度可以独立进行扩展。

2 类图

在这里插入图片描述

3 伪代码实现

public abstract class Abstraction {
    protected Implementor implementor;
    
    public Abstraction(Implementor implementor) {
        this.implementor = implementor;
    }
    
    public abstract void operation();
}

public class RefinedAbstraction extends Abstraction {
    public void RefinedAbstraction(Implementor implementor) {
        super(implementor);
    }
    
    public void operation() {
        implementor.operationImpl();
    }
}

public interface Implementor {
    void operationImpl();
}

public class ConcreteImplementorA {
    public void operationImpl() {
        
    }
}

public class ConcreteImplementorB {
    public void operationImpl() {
        
    }
}

4 使用场景

假设有两个手机品牌M和N,两个品牌都有游戏和通讯录,从面向对象的角度来设计,如果采用继承的方式,我们会做如下设计:
在这里插入图片描述

(引自大话设计模式)

在这里插入图片描述

(引自大话设计模式)

上面两种方式虽然采用了面向对象的设计方式,遵循了对修改关闭对扩展开放的设计原则,但是仔细想想,会出现什么问题?假设我们还有手机品牌H,I…,各类手机还有音乐软件、阅读软件等等其他软件,手机品牌和软件一组合,我们要编写的类就会出现指数级增长,这会导致系统越来越庞大,难以管理。

在这种情况下,我们就可以使用桥接模式,将继承改成组合的方式,增加一个手机品牌,我们只需增加一个品牌子类即可,增加一个软件,我们也只需增加一个类就行,新的手机品牌和新的软件功能只要组合起来就行了。

4.1 java代码

public interface IHandsetSoft {
    void run();
}

public class HandsetGame implements IHandsetSoft {
    @Override
    public void run() {
        System.out.println("运行手机游戏");
    }
}

public class HandsetAddressList implements IHandsetSoft {
    @Override
    public void run() {
        System.out.println("运行手机通讯录");
    }
}

public abstract class HandsetBrand {

    protected IHandsetSoft handsetSoft;

    public HandsetBrand(IHandsetSoft handsetSoft) {
        this.handsetSoft = handsetSoft;
    }

    public abstract void run();
}

public class HandsetBrandM extends HandsetBrand {
    public HandsetBrandM(IHandsetSoft handsetSoft) {
        super(handsetSoft);
    }

    @Override
    public void run() {
        System.out.println("手机品牌M");
        handsetSoft.run();
    }
}

public class HandsetBrandN extends HandsetBrand {
    public HandsetBrandN(IHandsetSoft handsetSoft) {
        super(handsetSoft);
    }

    @Override
    public void run() {
        System.out.println("手机品牌N");
        handsetSoft.run();
    }
}

public class Client {
    public static void main(String[] args) {
        // 手机游戏
        IHandsetSoft handsetGame = new HandsetGame();

        // 手机通讯录
        IHandsetSoft handsetAddressList = new HandsetAddressList();

        // 在手机品牌M上运行手机游戏
        HandsetBrand handsetBrandM = new HandsetBrandM(handsetGame);
        handsetBrandM.run();

        // 在手机品牌M上运行手机通讯录
        handsetBrandM = new HandsetBrandM(handsetAddressList);
        handsetBrandM.run();

        // 在手机品牌N上运行手机游戏
        HandsetBrand handsetBrandN = new HandsetBrandN(handsetGame);
        handsetBrandN.run();

        // 在手机品牌N上运行手机通讯录
        handsetBrandN = new HandsetBrandN(handsetGame);
        handsetBrandN.run();
    }
}

采用继承的方式,是一种紧耦合的方式,可以做扩展,但是比较困难,采用组合的方式是一种松耦合的方式,可以进行轻松的扩展。继承是is-a的关系,如果是is-a的关系,适合使用继承,组合是has-a的关系,如果是has-a的关系,适合使用组合。比如上面是手机上有手机游戏和手机通讯录,所以用组合更合适。
再比如红色长方形,绿色长方形,红色圆形,绿色圆形,可以理解为长方形或者原型具有红色或者绿色的属性,可以使用组合的方式。类图如下:
在这里插入图片描述

(引自https://www.runoob.com/design-pattern/bridge-pattern.html)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值