当前位置: 首页 > article >正文

设计模式(六)

设计模式(六)

组件构建过程中,某些接口之间的依赖常常会带来很多问题,甚至根本无法实现。采用添加一层间接稳定接口,来隔离本来互相紧密关联的接口是一种常见的解决方案

 1.门面(Facade):门面类知道哪些子系统负责处理哪些请求,将客户端的请求代理给适当的子系统对象
 2.子系统(Subsystem):实现子系统的功能。子系统并不意识到门面,它们接受请求并处理,通常是由多个类组成的复杂系统
 3.客户端(Client):使用门面来与子系统进行交互

eg:

 // 子系统类
 class Subsystem1 {
 public:
     void operation1() {
         // ...
     }
 };
 
 class Subsystem2 {
 public:
     void operation2() {
         // ...
     }
 };
 
 class Subsystem3 {
 public:
     void operation3() {
         // ...
     }
 };
 
 // 门面类
 class Facade {
 private:
     Subsystem1* subsystem1;
     Subsystem2* subsystem2;
     Subsystem3* subsystem3;
 
 public:
     Facade() {
         subsystem1 = new Subsystem1();
         subsystem2 = new Subsystem2();
         subsystem3 = new Subsystem3();
     }
 
     void operation() {
         subsystem1->operation1();
         subsystem2->operation2();
         subsystem3->operation3();
     }
 
     ~Facade() {
         delete subsystem1;
         delete subsystem2;
         delete subsystem3;
     }
 };
 
 // 客户端代码
 int main() {
     Facade* facade = new Facade();
     facade->operation();
     delete facade;
     return 0;
 }
 

代理模式

允许我们为其他对象提供一种代理以控制对这个对象的访问。代理模式的关键是提供一个替身或占位符,以控制对原始对象的访问

不改变原始对象代码的情况下,通过引入代理对象来间接访问原始对象,以添加额外的功能,如访问控制、日志记录、缓存等

1.抽象主题(Subject):定义了RealSubject和Proxy的共用接口,这样就可以使用代理来代替真实对象。
2.真实主题(RealSubject):定义了代理所代表的真实对象,代理会控制对它的访问。
3.代理(Proxy):保存一个引用使得代理可以访问真实对象,并提供一个与真实主题相同的接口。代理可以附加一些额外的功能,如权限验证、延迟加载等
// 抽象主题
class Image {
public:
    virtual void display() = 0;
};

// 真实主题
class RealImage : public Image {
private:
    string filename;

public:
    RealImage(string filename) {
        this->filename = filename;
        loadFromDisk();
    }

    void display() override {
        cout << "Displaying " << filename << endl;
    }

private:
    void loadFromDisk() {
        cout << "Loading " << filename << endl;
    }
};

// 代理
class ProxyImage : public Image {
private:
    RealImage* realImage;
    string filename;

public:
    ProxyImage(string filename) {
        this->filename = filename;
    }

    ~ProxyImage() {
        delete realImage;
    }

    void display() override {
        if (realImage == nullptr) {
            realImage = new RealImage(filename);
        }
        realImage->display();
    }
};

// 客户端代码
int main() {
    Image* image = new ProxyImage("test_image.jpg");

    // 图像将在第一次显示时加载
    image->display();
    cout << "---------------------" << endl;
    // 图像不会再次从磁盘加载
    image->display();

    delete image;
    return 0;
}

适配器模式

将一个类得接口转换成客户希望得另一个接口,Adapter模式使得原本由于接口不兼容而不能一起工作得那些类可以一起工作

1.目标接口(Target):定义客户端使用的接口,客户端期望与这个接口协同工作。
2.被适配者(Adaptee):一个已经存在的类或对象,其接口与目标接口不兼容。
3.适配器(Adapter):一个中介类,通过继承或组合的方式实现目标接口,并将目标接口的调用转化为被适配者接口的调用

eg:

// 目标接口
class Target {
public:
    virtual void request() = 0;
};

// 被适配者
class Adaptee {
public:
    void specificRequest() {
        // 实现特定的功能
    }
};

// 适配器
class Adapter : public Target {
private:
    Adaptee* adaptee;

public:
    Adapter(Adaptee* adaptee) {
        this->adaptee = adaptee;
    }

    void request() override {
        // 调用被适配者的方法以实现目标接口
        adaptee->specificRequest();
    }
};

// 客户端代码
int main() {
    Adaptee* adaptee = new Adaptee();
    Target* adapter = new Adapter(adaptee);

    // 客户端通过目标接口与适配器交互
    adapter->request();

    delete adaptee;
    delete adapter;
    return 0;
}

将目标接口与被适配者解耦,使得两者可以独立变化,通过引入一个适配器类,可以在不修改现有代码的基础上增加新的接口功能

中介模式

将多个对象间复杂得关系解耦,Mediator模式将多个对象间得控制逻辑进行集中管理,变多个对象互相关联 为多个对象和一个中介者关联,简化了系统得维护,抵御了可能得变化

将原理相互依赖得对象,现在使其分离,然后让所有对象和一个中间对象相互依赖

// 中介者接口
class Mediator {
public:
    virtual void send(std::string message, Colleague* sender) = 0;
};

// 同事接口
class Colleague {
protected:
    Mediator* mediator;
public:
    Colleague(Mediator* mediator) {
        this->mediator = mediator;
    }
};

// 具体的同事类
class ConcreteColleague1 : public Colleague {
public:
    ConcreteColleague1(Mediator* mediator) : Colleague(mediator) {}

    void send(std::string message) {
        mediator->send(message, this);
    }

    void notify(std::string message) {
        std::cout << "Colleague1 gets message: " << message << std::endl;
    }
};

class ConcreteColleague2 : public Colleague {
public:
    ConcreteColleague2(Mediator* mediator) : Colleague(mediator) {}

    void send(std::string message) {
        mediator->send(message, this);
    }

    void notify(std::string message) {
        std::cout << "Colleague2 gets message: " << message << std::endl;
    }
};

// 具体的中介者类
class ConcreteMediator : public Mediator {
private:
    ConcreteColleague1* colleague1;
    ConcreteColleague2* colleague2;
public:
    ConcreteMediator() : colleague1(nullptr), colleague2(nullptr) {}

    void setColleague1(ConcreteColleague1* colleague) {
        this->colleague1 = colleague;
    }

    void setColleague2(ConcreteColleague2* colleague) {
        this->colleague2 = colleague;
    }

    void send(std::string message, Colleague* sender) override {
        if (sender == colleague1) {
            colleague2->notify(message);
        } else {
            colleague1->notify(message);
        }
    }
};

// 客户端代码
int main() {
    ConcreteMediator mediator;
    ConcreteColleague1 colleague1(&mediator);
    ConcreteColleague2 colleague2(&mediator);

    mediator.setColleague1(&colleague1);
    mediator.setColleague2(&colleague2);

    colleague1.send("Hello from Colleague1");
    colleague2.send("Hello from Colleague2");

    return 0;
}

  1. 集中控制:所有消息传递的逻辑都集中在ConcreteMediator类中,这使得管理和修改消息传递规则变得更加容易
  2. 简化对象通信:同事对象不需要知道其他同事对象的存在或如何与它们通信。它们只需要知道如何与中介者通信

http://www.kler.cn/a/377468.html

相关文章:

  • vue2项目使用360安全浏览器默认采用极速模式打开运行
  • 【大数据学习 | HBASE】habse的表结构
  • VIM使用笔记
  • lego-loam mapOptmization 源码注释(四)
  • java.io.FileNotFoundException: Could not locate Hadoop executable: (详细解决方案)
  • MySQL-如果你在添加外键时忘加约束名,如何找到系统默认的约束名
  • Docker小记
  • 山海鲸报表VS微软Power BI:哪个报表工具更适合企业?
  • SQLite从入门到精通面试题及参考答案
  • 开源免费的API网关介绍与选型
  • 信息学科平台系统设计与实现:Spring Boot技术全解析
  • wps宏代码学习
  • 机器学习中常见特征选择方法介绍:特征过滤、特征组合、嵌入式方法、主成分分析、递归消除
  • 大厂面试真题-caffine比guava有什么提升?
  • nodejs 服务器实现负载均衡
  • CF1152F2 Neko Rules the Catniverse (Large Version) 题解(插入类dp,状压,矩阵乘法,dp技巧)
  • npm入门教程19:npm包管理
  • 【Python】-蚂蚁森林问答题-查看当天的答案
  • C#核心(5)构造,析构,垃圾回收
  • 开源模型应用落地-qwen模型小试-Qwen2.5-7B-Instruct-玩转ollama-Modelfile文件(二)
  • 光耦合器的关键作用和创新---腾恩科技
  • 力扣1658.将x减到0的最小操作数
  • vue-verify-plugin。vue项目表单验证插件
  • Unity3D学习FPS游戏(8)装弹和弹夹UI显示
  • Android开发之——SOLID基础设计原则(掌握23种设计模式)其实开发之路如此简单
  • 苹果转向 Apple Silicon,Intel Mac 的支持时限倒计时