将4年前的设计模式笔记再看一遍(5),Bridge

一、模式定义

子类急剧膨胀,需要重构,与Decorator一个分类。

将抽象部分(业务功能)与实现部分(平台实现)分离,使它们都可以独立的变化。

1、最初设计

arduino 复制代码
class Messager {
public:
    virtual void login(string username, string password) = 0;
    virtual void sendMessage(string message) = 0;
    virtual void sendPicture(Image image) = 0;
    
    virtual void playSound() = 0;
    virtual void drawShape() = 0;
    virtual void writeText() = 0;
    virtual void connect() = 0;
    
    virtual ~Messager() {}
};

// 平台实现
class PCMessagerBase: public Messager {
public:
    virtual void playSound() {
        // ...
    }
    
    virtual void drawShape() {
        // ...
    }
    virtual void writeText() {
        // ...
    }
    virtual void connect() {
        // ...
    }
};

class MobileMessagerBase: public Messager {
public:
    virtual void playSound() {
        // ...
    }
    
    virtual void drawShape() {
        // ...
    }
    virtual void writeText() {
        // ...
    }
    virtual void connect() {
        // ...
    }
};

// 业务抽象
class PCMessagerLite: public PCMessagerBase {
public:
    virtual void login(string username, string password) {
        PCMessagerBase::connect();
        // ...
    }
    
    virtual void sendMessage(string message) {
        PCMessagerBase::writeText();
        // ...
    }
    
    virtual void sendPicture(Image image) {
        PCMessagerBase::drawShape();
        // ...
    }
};

class PCMessagerPerfect: public PCMessagerBase {
public:
    virtual void login(string username, string password) {
        PCMessagerBase::playSound();
        // ***
        PCMessagerBase::connect();
        // ...
    }
    
    virtual void sendMessage(string message) {
        PCMessagerBase::playSound();
        // ***
        PCMessagerBase::writeText();
        // ...
    }
    
    virtual void sendPicture(Image image) {
        PCMessagerBase::playSound();
        // ***
        PCMessagerBase::drawShape();
        // ...
    }
};

class MobileMessagerLite: public MobileMessagerBase {
public:
    virtual void login(string username, string password) {
        MobileMessagerBase::connect();
        // ...
    }
    
    virtual void sendMessage(string message) {
        MobileMessagerBase::writeText();
        // ...
    }
    
    virtual void sendPicture(Image image) {
        MobileMessagerBase::drawShape();
        // ...
    }
};

class MobileMessagerPerfect: public MobileMessagerBase {
public:
    virtual void login(string username, string password) {
        MobileMessagerBase::playSound();
        // ***
        MobileMessagerBase::connect();
        // ...
    }
    
    virtual void sendMessage(string message) {
        MobileMessagerBase::playSound();
        // ***
        MobileMessagerBase::writeText();
        // ...
    }
    
    virtual void sendPicture(Image image) {
        MobileMessagerBase::playSound();
        // ***
        MobileMessagerBase::drawShape();
        // ...
    }
};

// 使用
void process() {
    Messager* m = new MobileMessagerPerfect();
}

类的数目:1+n+m*n

2、优化方式

继承转组合。

csharp 复制代码
// 业务抽象

// MobileMessagerLite与PCMessagerLite合成一个类
class MessagerLite: public Messager {
    Messager* messager; // new MessagerBase();
public:
    virtual void login(string username, string password) {
        messager->connect();
        // ...
    }
    
    virtual void sendMessage(string message) {
        messager->writeText();
        // ...
    }
    
    virtual void sendPicture(Image image) {
        messager->drawShape();
        // ...
    }
};

// PCMessagerPerfect与MobileMessagerPerfect合二为一
class MessagerPerfect: public Messager {
    Messager* messager;
public:
    virtual void login(string username, string password) {
        messager->playSound();
        // ***
        messager->connect();
        // ...
    }
    
    virtual void sendMessage(string message) {
        messager->playSound();
        // ***
        messager->writeText();
        // ...
    }
    
    virtual void sendPicture(Image image) {
        messager->playSound();
        // ***
        messager->drawShape();
        // ...
    }
};

3、解决问题

上面两个类出现之后,是有问题的。因为Messager* messager;这一行,因为他俩要是具体指定为PCMessagerBase或者MobileMessagerBase的时候,会报错。因为PCMessagerBase是纯虚类,不能实例化的。要将Messager拆分为两个类。

同时,如果两个子类有相同字段,需要提取到基类中去。

类的个数变为1 + n + m,但是运行时候,还是有n*m种方式。

csharp 复制代码
class MessagerImp {
    virtual void playSound() = 0;
    virtual void drawShape() = 0;
    virtual void writeText() = 0;
    virtual void connect() = 0;
    
    virtual ~MessagerImp() {}
};

class Messager {
    MessagerImp* messagerImp; // new PCMessagerBase();
    
public:
    Messager(MessagerImp* imp): messagerImp(imp) {}

    virtual void login(string username, string password) = 0;
    virtual void sendMessage(string message) = 0;
    virtual void sendPicture(Image image) = 0;
    
    virtual ~Messager() {}
};

// 平台实现
class PCMessagerImp: public MessagerImp {
public:
    virtual void playSound() {
        // ...
    }
    
    virtual void drawShape() {
        // ...
    }
    virtual void writeText() {
        // ...
    }
    virtual void connect() {
        // ...
    }
};

class MobileMessagerImp: public MessagerImp {
public:
    virtual void playSound() {
        // ...
    }
    
    virtual void drawShape() {
        // ...
    }
    virtual void writeText() {
        // ...
    }
    virtual void connect() {
        // ...
    }
};

// 业务抽象
class MessagerLite: public Messager {
public:
    virtual void login(string username, string password) {
        messagerImp->connect();
        // ...
    }
    
    virtual void sendMessage(string message) {
        messagerImp->writeText();
        // ...
    }
    
    virtual void sendPicture(Image image) {
        messagerImp->drawShape();
        // ...
    }
};

class MessagerPerfect: public Messager {
public:
    virtual void login(string username, string password) {
        messagerImp->playSound();
        // ***
        messagerImp->connect();
        // ...
    }
    
    virtual void sendMessage(string message) {
        messagerImp->playSound();
        // ***
        messagerImp->writeText();
        // ...
    }
    
    virtual void sendPicture(Image image) {
        messagerImp->playSound();
        // ***
        messagerImp->drawShape();
        // ...
    }
};

void process(){
    // 运行时装配
    MessagerImp* mImp = new PCMessagerImp();
    Messager* m = new Messager(mImp);
}

二、杂谈

1、整理之前看过一次,整理之时毫无印象。(4年后,此视频中对此模式的讲解,会跟C++语言有一些强关联性。抽象一些与语言无关的点是,如果发现相似的继承规则需要写两套时,就可以考虑是否可以将其中的某个继承提取为一个成员变量。)

2、继承自一个纯虚基类后,如果没有重写掉所有的纯虚函数,则这个继承后的子类,依然是一个纯虚基类。

3、桥模式和装饰器模式的区别是,装饰器模式可能会存在子类的组合,而桥模式简单些,是单链,不存在组合。

4、视频链接(4年后看自己的笔记,发现只是做了搬运,于是附上视频链接):www.youtube.com/watch?v=Qci...

5、另一个比较好的博客链接:refactoringguru.cn/design-patt...

相关推荐
我爱cope11 分钟前
【Agent智能体21 | 构建AI工作流的技巧-优化组件的常用方法】
人工智能·设计模式·语言模型·职场和发展
小bo波10 小时前
枚举实战
java·设计模式·枚举·后端开发·代码重构
不好听61314 小时前
Prompt 驱动 NLP:用大语言模型重新定义自然语言处理开发范式
设计模式·node.js·nlp
天文家16 小时前
深入理解装饰器与适配器:从设计模式到 Spring AOP 的工程实践
java·设计模式
workflower17 小时前
医院核心竞争力的四大重构
人工智能·安全·设计模式·重构·动态规划·scrum
折哥的程序人生 · 物流技术专研21 小时前
【电商多平台电子面单对接实战|第二篇】抖音代发电子面单对接:从“面条代码”到整洁架构的涅槃之路
设计模式·架构·系统架构·单元测试·代码规范·单一职责原则
葫芦和十三1 天前
范式之变|Agent 设计,换语言了
人工智能·设计模式
ourenjiang1 天前
【学习设计模式】原型模式
学习·设计模式·原型模式
贵慜_Derek1 天前
《从零实现 Agent 系统》连载 20|MCP 与 Code Execution:协议、档位与 Sidecar
人工智能·设计模式·架构
Sam_Deep_Thinking2 天前
结算分摊的策略模式:不同营销活动的扣点计算方案
java·设计模式·架构·系统架构