设计模式之委托模式

委托设计模式(Delegate Pattern)是一种行为设计模式,它允许一个对象将某些责任委托给另一个对象。在委托模式中,有两个主要角色:委托者(Delegator)和被委托者(Delegate)。委托者将任务委托给被委托者,而被委托者负责执行这些任务。

主要角色:

  1. 委托者(Delegator) :
    • 接受客户端的请求。
    • 将请求委托给被委托者。
    • 可以有自己的行为,也可以仅仅是将请求转发。
  2. 被委托者(Delegate) :
    • 负责执行具体的任务。
    • 可以是接口或者抽象类,使得委托者可以委托不同的实现。

优点:

  • 解耦:委托者和被委托者之间的解耦,使得它们可以独立变化。
  • 扩展性:可以很容易地添加新的被委托者,从而扩展功能。
  • 灵活性:委托者可以根据需要动态地改变被委托者。

缺点:

  • 复杂性:可能会增加系统的复杂性,因为需要维护委托关系。
  • 性能开销:委托可能会引入一些额外的性能开销。

实现步骤:

  1. 定义被委托者接口或抽象类。
  2. 实现具体的被委托者类。
  3. 定义委托者类,并在其中包含一个被委托者的引用或指针。
  4. 委托者将任务转发给被委托者。

示例:

下面是一个简单的委托模式实现示例:

cpp 复制代码
#include <iostream>
#include <string>
// 被委托者接口
class Printer {
public:
    virtual void print(std::string message) = 0;
    virtual ~Printer() {}
};
// 具体的被委托者实现
class ConsolePrinter : public Printer {
public:
    void print(std::string message) override {
        std::cout << "ConsolePrinter: " << message << std::endl;
    }
};
// 另一个被委托者实现
class FilePrinter : public Printer {
public:
    void print(std::string message) override {
        std::cout << "FilePrinter: " << message << " (saved to file)" << std::endl;
    }
};
// 委托者
class PrintManager {
private:
    Printer* printer; // 持有被委托者的引用
public:
    PrintManager(Printer* p) : printer(p) {}
    void setPrinter(Printer* p) {
        printer = p;
    }
    void print(std::string message) {
        if (printer != nullptr) {
            printer->print(message); // 委托给被委托者
        }
    }
};
int main() {
    ConsolePrinter consolePrinter;
    FilePrinter filePrinter;
    PrintManager manager(&consolePrinter);
    manager.print("Hello World!");
    // 更改被委托者
    manager.setPrinter(&filePrinter);
    manager.print("Hello File!");
    return 0;
}

在这个例子中,PrintManager 是委托者,它将打印任务委托给 ConsolePrinter 或 FilePrinter。通过这种方式,PrintManager 可以在不改变自身代码的情况下,灵活地改变打印行为。

注意,这里用到了多态。在提供的代码示例中,Printer* printer; 这一行声明了一个指向 Printer 类型的指针,这是一个抽象基类。多态在这里体现在以下几个方面:

  1. 基类指针指向派生类对象 :
    • Printer* printer; 可以指向任何继承自 Printer 的派生类对象,如 ConsolePrinter 或 FilePrinter。
  2. 虚函数 :
    • Printer 类中定义了一个虚函数 void print(std::string message);,这意味着在派生类中可以对这个函数进行重写(override)。
  3. 动态绑定 :
    • 当通过基类指针调用 print 方法时,会根据对象的实际类型来调用相应的派生类中的重写函数。这是运行时多态的体现。
      在 main 函数中,以下代码展示了多态的使用:
cpp 复制代码
ConsolePrinter consolePrinter;
FilePrinter filePrinter;
PrintManager manager(&consolePrinter);
manager.print("Hello World!");
// 更改被委托者
manager.setPrinter(&filePrinter);
manager.print("Hello File!");

在这里,PrintManager 的 print 方法通过基类指针 printer 调用 print 函数。由于 printer 指向的是 ConsolePrinter 对象,第一次调用 print 时,会调用 ConsolePrinter 的 print 方法。当 printer 被设置为指向 FilePrinter 对象时,再次调用 print 方法,则会调用 FilePrinter 的 print 方法。这就是多态的动态绑定行为。

相关推荐
高晶18 小时前
CANopen 在 BMS 系统中的 C 语言实战指南
设计模式·程序员
博风19 小时前
13、设计模式应用举例:工厂方法模式:创建药品对象
设计模式·工厂方法模式
代钦塔拉21 小时前
【C++/Qt 进阶】设计模式系列(5):适配器模式——给“不兼容的接口“贴一层翻译膜
c++·qt·设计模式
bigbread1 天前
策略模式 + 工厂方法模式在项目中的实战应用
设计模式
高晶1 天前
C 语言实现 BMS 系统中 SPI 通信协议实战指南
设计模式·程序员
代钦塔拉1 天前
【C++/Qt 进阶】设计模式系列(2):工厂模式——从游戏角色到披萨店
c++·算法·设计模式
高晶2 天前
2A3 单端甲类功放从零制作全攻略:电路设计、焊接调试到煲机维护一站式指南
前端·设计模式
代钦塔拉2 天前
【C++/Qt 进阶】设计模式系列(4):原型模式——用“克隆“代替“重新构造“
c++·qt·设计模式
博风2 天前
11、设计模式应用举例:迭代器模式:使用多个集合存储对象
设计模式·迭代器模式
日和雫2 天前
面向对象与面向过程,谁才是“银弹”?
设计模式