设计模式之委托模式

委托设计模式(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 是委托者,它将打印任务委托给 ConsolePrinterFilePrinter。通过这种方式,PrintManager 可以在不改变自身代码的情况下,灵活地改变打印行为。

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

  1. 基类指针指向派生类对象
    • Printer* printer; 可以指向任何继承自 Printer 的派生类对象,如 ConsolePrinterFilePrinter
  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!");

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

相关推荐
逮到647了44 分钟前
23种设计模式简述
设计模式
爱吃烤鸡翅的酸菜鱼2 小时前
【Java】封装位运算通用工具类——用一个整数字段替代几十个布尔列,极致节省存储空间
java·开发语言·设计模式·工具类·位运算·合成复用原则
geovindu3 小时前
go: Model,Interface,DAL ,Factory,BLL using mysql
开发语言·mysql·设计模式·golang·软件构建
guojb8244 小时前
当 Vue 3 遇上桥接模式:手把手教你优雅剥离虚拟滚动的业务大泥球
vue.js·设计模式
我登哥MVP4 小时前
【Spring6笔记】 - 15 - Spring中的八大设计模式
java·spring boot·笔记·spring·设计模式·intellij-idea
无籽西瓜a5 小时前
【西瓜带你学设计模式 | 第十六期 - 迭代器模式】迭代器模式 —— 统一遍历实现、优缺点与适用场景
java·后端·设计模式·迭代器模式·软件工程
程序员小寒5 小时前
JavaScript设计模式(十):模板方法模式实现与应用
前端·javascript·设计模式·模板方法模式
likerhood5 小时前
关于三种工厂的设计模式总结
设计模式
榴莲omega6 小时前
第14天:React 工程化与设计模式
前端·react.js·设计模式
dozenyaoyida1 天前
嵌入式设计模式之策略模式(1)
经验分享·设计模式·策略模式