结构型模式——桥接模式

一、介绍

桥接模式是将实现与抽象放在两个不同的类层次中,是两个层次可以独立改变,属于结构性模式,它是基于类的最小设计原则,通过使用封装,聚合及继承等行为,让不同的类承担不同的职责。主要特点是把抽象与具体行为实现分离开来,从而可以保持各部分的独立性以及应对他们的功能扩展。

二、需求说明

在这里插入图片描述
需求:对不同的电脑类型的不同品牌实现具体操作,比如有开机、关机、打游戏等操作。看上面的需求说明图,第一反应就是按部就班的按照传统的方式实现,类图就跟上面的需求说明图大同小异。但是传统的方式存在很多问题。

传统方式解决存在的问题:

  • 扩展性问题:扩展性问题俗称类爆炸,如果我们再增加一种电脑的形态(笔记本),就需要增加各个品牌电脑的类,同样如果我们增加一个电脑品牌,也需要在各个电脑形态类下增加相应的品牌。
  • 违反单一职责原则:当我们增加电脑形态时,需要增加所有品牌的电脑,必然增加代码的维护成本。

三、案例

  • 电脑品牌接口
/**
 * 电脑品牌能力接口
 *
 * @author zhangxs
 **/
public interface ComputerBrand {
    /** 开机 */
    void open();

    /** 关机 */
    void close();

    /** 打游戏 */
    void game();
}
  • 电脑形态抽象类
/**
 * 电脑形态 (台式机、笔记本、一体机)
 *
 * @author zhangxs
 **/
public abstract class ComputerType {
    /** 桥接模式的灵魂:组合 */
    protected ComputerBrand computerBrand;

    public ComputerType(ComputerBrand computerBrand) {
        this.computerBrand = computerBrand;
    }

    protected void open() {
        this.computerBrand.open();
    }

    protected void close() {
        this.computerBrand.close();
    }

    protected void game() {
        this.computerBrand.game();
    }
}
  • 台式机
/**
 * 台式机
 *
 * @author zhangxs
 **/
public class DesktopComputer extends ComputerType{

    public DesktopComputer(ComputerBrand computerBrand) {
        super(computerBrand);
    }

    @Override
    public void open() {
        super.open();
        System.out.println("台式电脑");
    }

    @Override
    public void close() {
        super.close();
        System.out.println("台式电脑");
    }

    @Override
    public void game() {
        super.game();
        System.out.println("台式电脑");
    }
}
  • 笔记本
/**
 * 笔记本
 *
 * @author zhangxs
 **/
public class NotebookComputer extends ComputerType {

    public NotebookComputer(ComputerBrand computerBrand) {
        super(computerBrand);
    }

    @Override
    public void open() {
        super.open();
        System.out.println("笔记本电脑");
    }

    @Override
    public void close() {
        super.close();
        System.out.println("笔记本电脑");
    }

    @Override
    public void game() {
        super.game();
        System.out.println("笔记本电脑");
    }
}
  • 一体机
/**
 * 一体机
 *
 * @author zhangxs
 **/
public class IntegrationComputer extends ComputerType {

    public IntegrationComputer(ComputerBrand computerBrand) {
        super(computerBrand);
    }

    @Override
    public void open() {
        super.open();
        System.out.println("一体式电脑");
    }

    @Override
    public void close() {
        super.close();
        System.out.println("一体式电脑");
    }

    @Override
    public void game() {
        super.game();
        System.out.println("一体式电脑");
    }
}
  • 联想
/**
 * 联想
 *
 * @author zhangxs
 **/
public class Lenovo implements ComputerBrand {

    @Override
    public void open() {
        System.out.println("联想开机");
    }

    @Override
    public void close() {
        System.out.println("联想关机");
    }

    @Override
    public void game() {
        System.out.println("联想打游戏");
    }
}
  • 华硕
/**
 * 华硕
 *
 * @author zhangxs
 **/
public class Asus implements ComputerBrand {

    @Override
    public void open() {
        System.out.println("华硕开机");
    }

    @Override
    public void close() {
        System.out.println("华硕关机");
    }

    @Override
    public void game() {
        System.out.println("华硕打游戏");
    }
}
  • 戴尔
/**
 * 戴尔
 *
 * @author zhangxs
 **/
public class Dell implements ComputerBrand {

    @Override
    public void open() {
        System.out.println("戴尔开机");
    }

    @Override
    public void close() {
        System.out.println("戴尔关机");
    }

    @Override
    public void game() {
        System.out.println("戴尔打游戏");
    }
}
  • 测试
/**
 * 测试
 *
 * @author zhangxs
 **/
public class Test {
    public static void main(String[] args) {
        // 华硕台式
        DesktopComputer asusDesktop = new DesktopComputer(new Asus());
        asusDesktop.open();
        asusDesktop.game();
        asusDesktop.close();

        // 联想笔记本
        NotebookComputer lenovoNotebook = new NotebookComputer(new Lenovo());
        lenovoNotebook.open();
        lenovoNotebook.game();
        lenovoNotebook.close();

        // 戴尔一体机
        IntegrationComputer dellIntegration = new IntegrationComputer(new Dell());
        dellIntegration.open();
        dellIntegration.game();
        dellIntegration.close();

        // 如果还想加一种形态,直接新建一个类,继承ComputerType类,无需其他任何修改
        // 如果还想加一种品牌,直接新建一个类,实现ComputerBrand接口,无需其他任何修改
    }
}

四、总结

  • 桥接模式使用时的注意事项喝细节:
    1、实现了抽象喝实现部分的分离,从而极大的提供了系统的灵活性,让抽象部分喝实现部分独立开来,这有助于系统进行分层设计,从而产生更好的结构化系统。
    2、对于系统的高层部分,只需要知道抽象部分和实现部分的接口即可,其他部分根据具体业务完成。
    3、桥接模式替代了多层继承的方案,可以减少子类的个数,降低系统的管理和维护成本。
    4、桥接模式的引入增加了系统的理解和设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象层进行设计,并面向抽象层编程。
    5、桥接模式要求正确识别出系统两个独立变化的维度(抽象和实现),因此其使用范围有一定的局限性,即需要有这样的场景。
    6、对于不希望使用继承或因为多层继承导致系统类的个数急剧增加的情况,比较适合使用桥接模式优化代码。
  • 常见的应用场景:
    1、在JDK中,JDBC驱动部分代码,就有桥接模式的影子,其中Driver接口,从桥接模式的角度来看即为抽象层接口,其下面包含了MySQL的Driver、Oracle的Driver等,这些就可以当作接口的实现类,具体的可以了解一下这部分源码
    2、银行转账系统:转账通过转账方式可以分为网上转账、柜台转账、ATM转账,而转账用户类型又可以分为普通用户、银卡用户、金卡用户等等。
    3、消息管理系统:消息类型可以分为即时消息、延时消息、消息来源又可以分为手机短信、邮件消息、qq消息…
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
桥接模式是一种结构设计模式,它将抽象和实现分离,使它们可以独立地变化。桥接模式的核心思想是将一个大类或一组类分解成抽象和实现两个独立的维度,使它们可以独立地变化和扩展,同时通过桥接来将它们连接起来。 在C++中,桥接模式通常通过虚函数实现。抽象部分通过基类定义接口,而实现部分通过派生类实现具体的功能。通过将抽象部分的指针作为参数传递给实现部分的函数,就可以实现两个部分的连接。 下面是一个简单的桥接模式的C++示例: ```c++ class Implementor { public: virtual void operation() = 0; virtual ~Implementor() {} }; class ConcreteImplementorA : public Implementor { public: void operation() override { // 具体的实现A } }; class ConcreteImplementorB : public Implementor { public: void operation() override { // 具体的实现B } }; class Abstraction { public: Abstraction(Implementor* implementor) : m_implementor(implementor) {} virtual void operation() = 0; virtual ~Abstraction() {} protected: Implementor* m_implementor; }; class RefinedAbstraction : public Abstraction { public: RefinedAbstraction(Implementor* implementor) : Abstraction(implementor) {} void operation() override { m_implementor->operation(); // 其他操作 } }; int main() { Implementor* implementorA = new ConcreteImplementorA(); Implementor* implementorB = new ConcreteImplementorB(); Abstraction* abstractionA = new RefinedAbstraction(implementorA); Abstraction* abstractionB = new RefinedAbstraction(implementorB); abstractionA->operation(); abstractionB->operation(); delete abstractionA; delete abstractionB; delete implementorA; delete implementorB; return 0; } ``` 在上面的示例中,Implementor是实现部分的抽象基类,ConcreteImplementorA和ConcreteImplementorB是具体的实现类。Abstraction是抽象部分的基类,RefinedAbstraction是抽象部分的具体实现类。在main函数中,我们创建了不同的Implementor和Abstraction对象,并通过它们来完成不同的操作。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值