设计模式之委托模式

委托设计模式(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 方法。这就是多态的动态绑定行为。

相关推荐
摘星编程8 分钟前
并发设计模式实战系列(6):读写锁
java·设计模式·并发编程
Allen Bright2 小时前
【设计模式-4】深入理解设计模式:工厂模式详解
设计模式
碎梦归途3 小时前
23种设计模式-结构型模式之适配器模式(Java版本)
java·开发语言·jvm·单例模式·设计模式·适配器模式
风,停下4 小时前
C#基于Sunnyui框架和MVC模式实现用户登录管理
设计模式·c#·mvc
苏近之6 小时前
说明白 Rust 中的泛型: 泛型是一种多态
设计模式·rust
Pasregret6 小时前
中介者模式:解耦对象间复杂交互的设计模式
设计模式·交互·中介者模式
前端大白话8 小时前
前端必学!CSS gap属性在Flexbox和Grid布局中的“间距魔法”
前端·css·设计模式
牛奶咖啡139 小时前
学习设计模式《五》——工厂方法模式
学习·设计模式·工厂方法模式·ioc/di·参数化工厂方法
渊渟岳9 小时前
学习设计模式有这两就够了:手册+实战项目
设计模式
Pasregret15 小时前
迭代器模式:统一数据遍历方式的设计模式
设计模式·迭代器模式