行为型模式【委派模式】
委派模式又叫委托模式,是一种面向对象的设计模式,允许对象组合实现与继承相同的代码重用。它的基本作用就是负责任务的调用和分配任务,是一种特殊的静态代理,可以理解为全权代理,但是代理模式注重过程,而委派模式注重结果。
从类图中我们可以看到,委派模式有三个参与角色:
抽象任务角色(Task):定义一个抽象接口,它有若干个实现类。
委派者角色(Cook , Cashier):负责在各个具体角色实列之间做出决策,并判断并调用具体实现方法。
具体任务角色(Manager):真正执行任务的角色
现实生活中的委派场景发生,如:老板boss给一个经理下达任务,经理会根据具体情况给每个员工派发工作任务,待员工把任务做完之后,再由经理汇报工作进度和结果给老板
//抽象任务角色(Task)
public interface Task {
void doTask(String taskName);
}
// 委派者角色(Cook , Cashier):负责在各个具体角色实列之间做出决策,并判断并调用具体实现方法。
public class Cook implements Task {
private String userName = "邓紫棋厨师";
@Override
public void doTask(String taskName) {
System.out.println("这个任务主要是:" + taskName + "需要由:" + userName);
}
}
public class Cashier implements Task {
private String userName = "周杰伦收银员";
@Override
public void doTask(String taskName) {
System.out.println("这个任务主要是:" + taskName + "需要由:" + userName);
}
}
// 具体任务角色(Manager):真正执行任务的角色
public class Manager implements Task {
private static Map<String, Task> map;
static {
map = new HashMap<>();
map.put("炒菜", new Cook());
map.put("收款", new Cashier());
}
@Override
public void doTask(String taskName) {
if (!map.containsKey(taskName)) {
System.out.println("这点钱很难办成这个任务,可能需要重新加员工处理");
return;
}
map.get(taskName).doTask(taskName);
}
}
// 老板
public class boss {
public void doTask(String taskName, Task task) {
task.doTask(taskName);
}
}
public class Test {
public static void main(String[] args) {
new boss().doTask("炒菜",new Manager());
new boss().doTask("收款",new Manager());
new boss().doTask("端菜",new Manager());
}
}
委派模式的优缺点
优点:
通过任务委派能够将一个大型的任务细化,然后通过统一管理这些子任务的完成情况实现任务的跟进,能够加快任务执行的效率
缺点:
任务委派方式需要根据任务的复杂程度进行不同的改变,在任务比较复杂的情况下可能需要进行多重委派,容易造成混乱。
源码当中的委派模式
ClassLoader // 双亲委派机制的委派模式,
protected Class<?> loadClass(String name, boolean resolve){
Class<?> c = findLoadedClass(name); // 校验当前是否加载过
if (c == null) { // 未加载
long t0 = System.nanoTime();
try {
if (parent != null) { // 判断是否还有父类
c = parent.loadClass(name, false);
} else {
c = findBootstrapClassOrNull(name); // 如果没有,自己在去加载
}
........
return c;
}
java.lang.reflect.Method // 委派模式
public Object invoke(Object obj, Object... args)
throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException
{
.....
MethodAccessor ma = methodAccessor; //委派对象 // read volatile
if (ma == null) {
ma = acquireMethodAccessor(); // 委派对象
}
return ma.invoke(obj, args);//通过当前类中的methodAccessor对象后负责去委派执行
}
// spring 的委派模式
DefaultBeanDefinitionDocumentReader // 类中的委派机制
protected void doRegisterBeanDefinitions(Element root) {
.......
preProcessXml(root);
parseBeanDefinitions(root, this.delegate); // 讲不同的element格式的表委派给不同的类处理并返回结果
postProcessXml(root);
this.delegate = parent;
}