设计模式-委派模式
# 七大软件设计原则 # 设计模式-工厂模式 # 设计模式-单例模式 # 设计模式-原型模式 # 设计模式-策略模式 # 设计模式-责任链模式 # 设计模式-建造者模式 # 设计模式-深度分析代理模式 # 设计模式-门面模式 # 设计模式-装饰器模式 # 设计模式-享元模式 # 设计模式-组合模式 # 设计模式-适配器模式 # 设计模式-桥接模式
委派模式(Delegate Pattern)又叫委托模式,是一种面向对象的设计模式,允许对象组合实现与 继承相同的代码重用。它的基本作用就是负责任务的调用和分配任务,是一种特殊的静态代理,可以理 解为全权代理,但是代理模式注重过程,而委派模式注重结果。委派模式属于行为型模式,不属于 GOF 23 种设计模式中。
通俗点讲就是有两个对象参与(两个对象协同)处理同一个请求,接受请求的对象将请求委托给另一个对象来处理。
委派模式的UML类图
可以发现和静态代理类的类图一样,所以也叫做特殊的静态代理,唯一的区别就是关注点不一样,一个是过程一个是结果
代码如下:
public interface Task {
void doSomething();
}
public class ConcreteA implements Task{
@Override
public void doSomething() {
System.out.println("ConcreteA doSomething");
}
}
public class ConcreteB implements Task{
@Override
public void doSomething() {
System.out.println("ConcreteB doSomething");
}
}
public class Delegate implements Task{
private Task task = new ConcreteA();
@Override
public void doSomething() {
task.doSomething();
}
public void toA(){
task = new ConcreteA();
}
public void toB(){
task = new ConcreteB();
}
}
public class Test {
public static void main(String[] args) {
Delegate delegate = new Delegate();
delegate.doSomething();
delegate.toB();
delegate.doSomething();
}
}
代码示例
举个典型的例子:路由,我们知道路由的作用就是在不同网段之间转发数据的,当路由器接受到一个消息的时候她会根据消息头部中的信息找出对应网段再根据自己的路由表找到对应的机器再转发给实际接收者,这里面路由就是一个委托者角色而注册到这个路由中的计算机则是实际执行任务的角色(实际接收消息的角色) 消息体:
@Data
public class Message {
private String content;
private String targetIp;
private String sourceIp;
public Message(String content, String targetIp, String sourceIp) {
this.content = content;
this.targetIp = targetIp;
this.sourceIp = sourceIp;
}
}
-
首先抽象出任务的角色
public interface IMessage { void receiveMessage(Message message); }
-
具体任务实现对象
@Data public class ComputerA implements IMessage{ private String ip = "192.168.88.7"; @Override public void receiveMessage(Message message) { System.out.println("ComputerA处理消息:" + message.getContent()); } }
@Data public class ComputerB implements IMessage{ private String ip = "192.168.88.8"; @Override public void receiveMessage(Message message) { System.out.println("ComputerB处理消息:" + message.getContent()); }
@Data public class ComputerC implements IMessage{ private String ip = "192.168.88.9"; @Override public void receiveMessage(Message message) { System.out.println("Computerc处理消息:" + message.getContent()); } }
-
委托者角色
public class Route implements IMessage{ private final Map<String, IMessage> routeTable= new HashMap<>(); public Route(){ ComputerA computerA = new ComputerA(); ComputerB computerB = new ComputerB(); ComputerC computerC = new ComputerC(); routeTable.put(computerA.getIp(),computerA); routeTable.put(computerB.getIp(),computerB); routeTable.put(computerC.getIp(),computerC); } @Override public void receiveMessage(Message message) { if(routeTable.containsKey(message.getTargetIp())){ routeTable.get(message.getTargetIp()).receiveMessage(message); } } }
这里用了策略模式配合使用
-
客户端调用
public class Test { public static void main(String[] args) { Message message = new Message("hello","192.168.88.7","192.168.88.100"); Route route = new Route(); route.receiveMessage(message); } }
-
打印结果
-
UML类图
源码中的应用
jvm在加载类的时候使用的就是双亲委派,就是在加载类之前会先找父类,如果存在父类则继续找父类的父类知道找到最顶级的父类然后加载返回即可,如果没有父类则加载类然后返回,具体源码我们可以看一下 ClassLoader
这个类:
委派模式优缺点
优点:
- 通过任务委派能够将一个大型的任务细化。
- 将应用相关的内容与框架完全分离开
- 避免过多的子类以及子类与父类的耦合
- 通过委托传递消息机制实现分层解耦
缺点: 任务委派方式需要根据任务的复杂程度进行不同的改变,在任务比较复杂的情况下可能需要进行多 重委派,容易造成紊乱。
转载自:https://juejin.cn/post/7173950620238348302