# 七大软件规划准则
# 规划形式-工厂形式
# 规划形式-单例形式
# 规划形式-原型形式
# 规划形式-策略形式
# 规划形式-责任链形式
# 规划形式-建造者形式
# 规划形式-深度剖析署理形式
# 规划形式-门面形式
# 规划形式-装饰器形式
# 规划形式-享元形式
# 规划形式-组合形式
# 规划形式-适配器形式
# 规划形式-桥接形式
派遣形式(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
这个类:
派遣形式优缺陷
优点:
- 经过使命派遣能够将一个大型的使命细化。
- 将使用相关的内容与框架彻底分脱离
- 防止过多的子类以及子类与父类的耦合
- 经过托付传递音讯机制完成分层解耦
缺陷:
使命派遣方法需求根据使命的杂乱程度进行不同的改变,在使命比较杂乱的情况下可能需求进行多
重派遣,容易造成紊乱。