Java 中的委托模式:掌握高效的任务分配
大约 2 分钟
也称为
- 助手
- 代理
委托设计模式的意图
允许一个对象将对一项任务的责任委托给另一个助手对象。
使用真实示例详细解释委托模式
现实世界中的例子
在一家餐馆,主厨将任务委托给副厨:一个负责烧烤,另一个负责沙拉,第三个负责甜点。每个副厨都专注于自己的领域,使主厨能够专注于整体厨房管理。这反映了委托设计模式,其中一个主对象将特定任务委托给助手对象,每个助手对象都是其领域的专家。
通俗地说
委托是一种设计模式,其中一个对象将任务传递给一个助手对象。
维基百科说
在面向对象编程中,委托是指在另一个原始对象(发送者)的上下文中评估一个对象的成员(属性或方法)(接收者)。委托可以显式进行,方法是将发送对象传递给接收对象,这可以在任何面向对象语言中完成;或者隐式进行,方法是通过语言的成员查找规则,这需要语言对该功能的支持。
Java 中委托模式的编程示例
让我们考虑一个打印示例。
我们有一个接口Printer
和三个实现CanonPrinter
、EpsonPrinter
和HpPrinter
。
public interface Printer {
void print(final String message);
}
@Slf4j
public class CanonPrinter implements Printer {
@Override
public void print(String message) {
LOGGER.info("Canon Printer : {}", message);
}
}
@Slf4j
public class EpsonPrinter implements Printer {
@Override
public void print(String message) {
LOGGER.info("Epson Printer : {}", message);
}
}
@Slf4j
public class HpPrinter implements Printer {
@Override
public void print(String message) {
LOGGER.info("HP Printer : {}", message);
}
}
PrinterController
可以通过将此接口处理的任何工作委托给实现它的对象来用作Printer
。
public class PrinterController implements Printer {
private final Printer printer;
public PrinterController(Printer printer) {
this.printer = printer;
}
@Override
public void print(String message) {
printer.print(message);
}
}
在客户端代码中,打印机控制器可以根据它们委托该工作的对象的不同,以不同的方式打印消息。
public class App {
private static final String MESSAGE_TO_PRINT = "hello world";
public static void main(String[] args) {
var hpPrinterController = new PrinterController(new HpPrinter());
var canonPrinterController = new PrinterController(new CanonPrinter());
var epsonPrinterController = new PrinterController(new EpsonPrinter());
hpPrinterController.print(MESSAGE_TO_PRINT);
canonPrinterController.print(MESSAGE_TO_PRINT);
epsonPrinterController.print(MESSAGE_TO_PRINT);
}
}
程序输出
HP Printer:hello world
Canon Printer:hello world
Epson Printer:hello world
使用真实示例详细解释委托模式

何时在 Java 中使用委托模式
- 当您希望将责任从一个类传递给另一个类而无需继承时。
- 为了实现基于组合的重用,而不是基于继承的重用。
- 当您需要在运行时使用多个可互换的助手类时。
Java 中委托模式的现实应用
- Java 的 java.awt.event 包,其中经常使用监听器来处理事件。
- Java 集合框架 (java.util.Collections) 中的包装类,它们委托给其他集合对象。
- 在 Spring 框架中,委托在 IoC 容器中被广泛使用,其中 bean 将任务委托给其他 bean。
委托模式的优缺点
优点
- 减少子类化:对象可以将操作委托给不同的对象并在运行时更改它们,从而减少对子类化的需求。
- 鼓励重用:委托促进了助手对象的代码重用。
- 提高灵活性:通过将任务委托给助手对象,您可以更改类在运行时的行为。
权衡
- 运行时开销:委托可能会引入额外的间接层,这可能会导致轻微的性能成本。
- 复杂性:设计可能会变得更加复杂,因为它涉及额外的类和接口来管理委托。
相关的 Java 设计模式
- 组合模式:委托可以在组合模式中使用,将组件特定的行为委托给子组件。
- 策略模式:委托通常在策略模式中使用,其中上下文对象将任务委托给策略对象。
- https://design-patterns.java-lang.cn/patterns/proxy/: 代理模式是一种委托形式,其中代理对象控制对另一个对象的访问,并将工作委托给该对象。