18.设计模式-桥接模式

桥接模式(Bridge):将抽象部分与它的实现部分分离,使它们都可以独立地变化

合成/聚合复用原则(CARP),尽量使用合成/聚合,尽量不要使用类继承。

由于实现的方式有多种,桥接模式的核心意图就是把这些实现独立出来,让它们各自地变化。这就使得每种实现的变化不会影响其他实现,从而达到应对变化的目的。

代码

本例中就是让'手机'既可以按照品牌来分类,也可以按照功能来分类。当品牌需要实现功能时,通过调用功能类实现。

业务类

c 复制代码
#include <stdio.h>
#include <stdlib.h>

typedef struct HandsetSoft {
    void (*run)();
} HandsetSoft;
typedef struct HandsetGame {
    HandsetSoft base;
} HandsetGame;

void HandsetGameRun() {
    printf("运行手机游戏\n");
}

HandsetSoft *InitHandsetGame() {
    HandsetGame *obj = (HandsetGame *)malloc(sizeof(HandsetGame));
    obj->base.run = HandsetGameRun;
    return (HandsetSoft *)obj;
}

typedef struct HandsetAddressList {
    HandsetSoft base;
} HandsetAddressList;
void HandsetAddressListRun() {
    printf("运行手机通讯录\n");
}

HandsetSoft *InitHandsetAddressList() {
    HandsetAddressList *obj = (HandsetAddressList *)malloc(sizeof(HandsetAddressList));
    obj->base.run = HandsetAddressListRun;
    return (HandsetSoft *)obj;
}
typedef struct HandsetBrand {
    HandsetSoft *soft;
    void (*run)(struct HandsetBrand *);
    void (*setSoft)(struct HandsetBrand *, struct HandsetSoft *);
} HandsetBrand;

typedef struct HandsetBrandN {
    HandsetBrand base;
} HandsetBrandN;

void HandsetBrandNSetSoft(HandsetBrand *obj, HandsetSoft *soft) {
    obj->soft = soft;
}

void HandsetBrandNRun(HandsetBrand *obj) {
    printf("手机品牌N ");
    obj->soft->run();
}

HandsetBrand *InitHandsetBrandN() {
    HandsetBrandN *obj = (HandsetBrandN *)malloc(sizeof(HandsetBrandN));
    obj->base.setSoft = HandsetBrandNSetSoft;
    obj->base.run = HandsetBrandNRun;
    return (HandsetBrand *)obj;
}

typedef struct HandsetBrandM {
    HandsetBrand base;
} HandsetBrandM;

void HandsetBrandMSetSoft(HandsetBrand *obj, HandsetSoft *soft) {
    if(obj->soft != NULL) {
        free(obj->soft);
    }
    obj->soft = soft;
}

void HandsetBrandMRun(HandsetBrand *obj) {
    printf("手机品牌M ");
    obj->soft->run();
}

HandsetBrand *InitHandsetBrandM() {
    HandsetBrandM *obj = (HandsetBrandM *)malloc(sizeof(HandsetBrandM));
    obj->base.setSoft = HandsetBrandMSetSoft;
    obj->base.run = HandsetBrandMRun;
    obj->base.soft = NULL;
    return (HandsetBrand *)obj;
}

客户端

c 复制代码
int main() {
    HandsetBrand *ab = InitHandsetBrandN();
    ab->setSoft(ab, InitHandsetGame());
    ab->run(ab);
    ab->setSoft(ab,InitHandsetAddressList());
    ab->run(ab);
    free(ab->soft);
    free(ab);
    ab = InitHandsetBrandM();
    ab->setSoft(ab, InitHandsetGame());
    ab->run(ab);
    ab->setSoft(ab, InitHandsetAddressList());
    ab->run(ab);
    free(ab->soft);
    free(ab);
    return 0;
}

UML图

总结

  • 合成/聚合复用原则的好处:优先使用对象的合成/聚合将有助于你保持每个类被封装,并被集中在单个任务上。这样类和类继承层次会保持较小规模,并且不太可能增长为不可控制的庞然大物。
相关推荐
evans在进步9 小时前
Java 常用设计模式入门:建造者、工厂、单例、外观与代理
java·python·设计模式
字节跳动开源15 小时前
VisActor全新图可视化开源项目:VGraph
前端·设计模式·开源
码匠许师傅16 小时前
【设计模式精讲】11.桥接模式(Bridge)
c++·设计模式·桥接模式·uml
学习星球2 天前
AI Agent 成本工程实战:从 OpenAI Codex 的 8 个“烧 Token“Bug 学起
人工智能·设计模式·微信小程序
AI人工智能+电脑小能手2 天前
大白话说Java设计模式-46-责任链模式(业务实战篇)
java·设计模式·责任链模式·风控校验·servlet filter·spring interceptor·链式处理
码匠许师傅3 天前
【设计模式精讲】7.建造者模式(Builder)
设计模式·建造者模式
码匠许师傅3 天前
【设计模式精讲】6.抽象工厂(Abstract Factory)
c++·设计模式
workflower3 天前
人形机器人灵巧手产业链
人工智能·设计模式·机器人·云计算·无人机
Java后端的Ai之路3 天前
03、Python - 抽象工厂模式
开发语言·python·设计模式·抽象工厂模式·通用智慧
AI人工智能+电脑小能手4 天前
大白话说Java设计模式-45-解释器模式(源码剖析篇)
java·设计模式·解释器模式·源码分析·pattern·spel·javacc