设计模式-委托模式

发布时间:2024年01月23日
设计模式专栏


模式介绍

委托模式是一种行为模式,用于在面向对象设计中解决多个对象接收并处理同一请求的问题。它通过将请求委托给另一个对象来统一处理请求,提高程序的性能和降低内存空间的使用。

委托模式利用了事件的冒泡机制,将一个或一组元素的事件委托给它们的父层或更外层元素上。真正绑定事件的是外层元素,当事件响应到需要绑定的元素上时,会通过事件冒泡机制触发外层元素的绑定事件,然后在该元素上执行函数。

这种模式的优点在于可以减少重复的代码,提高代码的可重用性和可维护性。同时,它也可以降低系统的耦合度,使系统更加灵活和易于扩展。

与代理模式相比,委托模式更注重结果而非过程。委托模式的核心是静态代理和策略模式的一种特殊组合。委托模式通常在需求中实现,例如商城系统和礼物系统需求,程序员可以通过委托模式将任务委派给其他对象处理,从而提高程序的可扩展性和灵活性。

在这里插入图片描述

模式特点

委托模式的优点主要包括:

  1. 解耦:委托模式有助于减少对象间的耦合度,使得对象之间的关系更加清晰和简单。
  2. 灵活性:通过委托,可以将一个任务的执行委派给其他对象,这使得程序更加灵活,便于进行功能扩展和维护。
  3. 复用性:通过将类似的任务委派给相同的对象处理,可以避免代码的重复,提高代码的复用性。
  4. 集中处理:可以将分散的任务集中处理,便于进行任务管理和任务调度。

委托模式的缺点主要包括:

  1. 性能影响:由于需要额外进行委托操作,可能会对性能产生一定影响。
  2. 过度依赖:如果过度使用委托模式,可能会导致代码结构变得复杂,增加维护的难度。
  3. 安全性问题:如果对委托的对象没有进行合适的检查和验证,可能会引入安全风险。
  4. 可能产生循环依赖:在某些情况下,委托可能会产生循环依赖的问题,使得程序难以理解和维护。

在这里插入图片描述

应用场景

委托模式在编程中有许多应用场景,以下是其中几个具体的例子:

  1. 事件处理:在图形用户界面(GUI)编程中,事件处理是一个常见的应用场景。当用户与界面进行交互(如点击按钮、输入文本等)时,可以触发相应的事件。通过委托模式,可以将这些事件的处理逻辑委托给特定的方法或函数,从而实现事件与处理逻辑的解耦。
  2. 回调函数:委托模式也常用于实现回调函数。在某些情况下,需要将一个任务的执行结果通知给另一个对象。通过委托模式,可以将回调函数作为参数传递给任务执行方法,在任务完成后调用回调函数,从而将结果通知给相应的对象。
  3. 多线程编程:在多线程编程中,委托模式可以用于实现线程之间的通信和协作。例如,可以将一个线程中的任务委托给另一个线程来处理,或者通过委托模式实现线程之间的数据共享和同步。
  4. 插件系统:在开发插件系统时,委托模式可以用于实现插件之间的解耦和扩展性。通过将插件的功能以委托的形式暴露出来,主程序可以在运行时动态地加载和卸载插件,从而实现功能的扩展和定制。

具体到代码层面,比如在C#中,可以使用委托(delegate)来实现委托模式。委托类型定义了可以引用的方法的类型,可以将方法作为参数传递给其他方法,或者将方法赋值给变量,以便稍后调用。这使得委托模式在C#中广泛应用于事件处理、回调函数、多线程编程等场景。

以上内容仅供参考,如需更多信息,建议查阅相关文献或咨询编程专家。

在这里插入图片描述

委托模式与代理模式的区别

委托模式与代理模式在多个方面存在差异:

  1. 行使权利的名义:代理包括委托代理、法定代理、指定代理三种类型,其中法定代理和指定代理是由法律规定的,而委托则是在双方诚信的基础上,通过合同的方式确定的民事法律活动。
  2. 从事的事务:代理涉及的行为以意思表示为要素,因此代理的一定是民事法律行为。而委托不要求以“意思表示”为要素,因此委托从事的行为可以是纯粹的事务性行为。
  3. 涉及的当事人:代理涉及三方当事人,即被代理人、代理人、第三人。而委托则属于双方当事人之间的关系,即委托人、受托人。
  4. 法律约束力:代理关系的法律效力与三方有关,而委托合同与代理关系不同,其法律约束力仅限于委托人和受托人,与第三人无关。
  5. 实现功能:从实现功能上讲,代理是提供一种“一个类对另外一个类的控制权”,是类与类之间关系。委托提供了“一种方法的执行会同时执行加载在上面的方法”,是方法与方法之间的关系。
  6. 执行方法:委托对象所加载的方法不一定要属于同一个类,但代理的类必须属于同一个类。

总的来说,委托模式与代理模式各有特点,在实际应用中应根据具体情况选择合适的方式。

在这里插入图片描述

代码示例

Java实现委托模式

在Java中,可以通过接口和回调函数来实现委托模式。以下是一个简单的示例:

// 定义委托接口
interface Delegate {
    void execute();
}

// 实现委托接口的类
class ConcreteDelegate implements Delegate {
    @Override
    public void execute() {
        System.out.println("ConcreteDelegate.execute()");
    }
}

// 委托接收者类
class Receiver {
    private Delegate delegate;

    public void setDelegate(Delegate delegate) {
        this.delegate = delegate;
    }

    public void action() {
        delegate.execute();
    }
}

// 委托调用者类
class Invoker {
    private Receiver receiver;

    public Invoker(Receiver receiver) {
        this.receiver = receiver;
    }

    public void setDelegate(Delegate delegate) {
        receiver.setDelegate(delegate);
    }

    public void execute() {
        receiver.action();
    }
}

// 测试代码
public class Main {
    public static void main(String[] args) {
        Receiver receiver = new Receiver();
        Invoker invoker = new Invoker(receiver);
        ConcreteDelegate concreteDelegate = new ConcreteDelegate();
        invoker.setDelegate(concreteDelegate); // 设置委托接收者对象中的委托对象为ConcreteDelegate对象
        invoker.execute(); // 执行委托调用者对象的execute方法,间接执行了ConcreteDelegate对象的execute方法,实现了委托模式的功能。
    }
}

在上述代码中,通过定义Delegate接口和ConcreteDelegate类来实现委托模式。Receiver类作为委托接收者,Invoker类作为委托调用者。在Invoker类中,通过调用Receiver类的setDelegate()方法来设置委托对象,然后通过调用execute()方法来执行委托调用者对象的操作,间接执行了委托对象的操作,实现了委托模式的功能。

Python实现委托模式

在Python中,委托模式可以通过使用类和函数来实现。以下是一个简单的示例:

class Delegate:
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        return self.func(*args, **kwargs)

class Receiver:
    def __init__(self):
        self.delegate = None

    def set_delegate(self, delegate):
        self.delegate = delegate

    def action(self):
        if self.delegate:
            self.delegate()

class Invoker:
    def __init__(self, receiver):
        self.receiver = receiver

    def set_delegate(self, delegate):
        self.receiver.set_delegate(delegate)

    def execute(self):
        self.receiver.action()

def concrete_delegate():
    print("ConcreteDelegate.execute()")

# 测试代码
receiver = Receiver()
invoker = Invoker(receiver)
invoker.set_delegate(Delegate(concrete_delegate))  # 设置委托接收者对象中的委托函数为concrete_delegate函数
invoker.execute()  # 执行委托调用者对象的execute方法,间接执行了concrete_delegate函数,实现了委托模式的功能。

在上述代码中,Delegate类是一个代理类,它接受一个函数作为参数,并将其存储在func属性中。__call__方法允许代理对象像函数一样被调用。Receiver类作为委托接收者,Invoker类作为委托调用者。在Invoker类中,通过调用Receiver类的set_delegate()方法来设置委托函数,然后通过调用execute()方法来执行委托调用者对象的操作,间接执行了委托函数,实现了委托模式的功能。

在这里插入图片描述

委托模式在spring中的应用

在Spring框架中,委托模式有多种应用场景,以下是其中几个例子:

  1. 监听器(Listener):Spring中的监听器,比如ApplicationListener,就是一个典型的委托模式的应用。在各个阶段发布事件,Spring会调用相应的监听器,这就是一个委派的过程。
  2. 代理模式:Spring的AOP(面向切面编程)就是一种特殊的代理模式,它允许程序员定义“切面”,在方法的调用之前、之后或者抛出异常的时候执行特定的代码。
  3. 模板模式:在Spring的JdbcTemplate中,execute()方法就是模板模式的一个应用。子类只需要实现具体的步骤,而不需要关心整体的流程。
  4. 策略模式:在Spring实例化对象的时候,可能会用到策略模式。例如,用户可以选择使用不同的算法解决同一个问题,这可以通过策略模式实现。
  5. 委派模式:SpringMVC框架中的DispatcherServlet实际上就使用了委派模式。它负责任务的调用和分配,类似于全权代理。

在这里插入图片描述

设计模式-注册模式

设计模式-外观模式

文章来源:https://blog.csdn.net/zhangzehai2234/article/details/135760402
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。