抽象任务角色(Task):定义一个抽象接口,它有若干实现类。
委派者角色(Delegate):负责在各个具体角色实例之间做出决策,并判断并调用具体实现的方法。
具体任务角色(Concrete) :真正执行任务的角色
现实场景:老板(Boss)给项目经理(Leader)下达任务,项目经理会根据实际情况给每个员工派发工作任务,待员工把工作任务完成之后,再由项目经理汇报工走进度和结果给老板。
创建IEmployee员工接口:
public interface IEmployee {
/**
* 执行任务
* @param task
*/
void doing(String task);
}
创建员工EmployeeA类:
public class EmployeeA implements IEmployee{
protected String goodAt="编程";
@Override
public void doing(String task) {
System.out.println("我是员工A,我擅长"+goodAt+",我现在开始做"+task+"工作");
}
}
创建员工EmployeeB类
public class EmployeeB implements IEmployee{
protected String goodAt="平面设计";
@Override
public void doing(String task) {
System.out.println("我是员工B,我擅长"+goodAt+",我现在开始做"+task+"工作");
}
}
创建项目经理Leader类:
public class Leader implements IEmployee{
private Map<String, IEmployee> employee=new HashMap<>();
@SuppressWarnings("all")
public Leader(){
employee.put("爬虫",new EmployeeA());
employee.put("海报图",new EmployeeB());
}
@Override
public void doing(String task) {
if(!employee.containsKey(task)){
System.out.println("这个任务"+task+"超出我的能力范围");
return;
}
employee.get(task).doing(task);
}
}
创建Boss下达命令:
public class Boss {
public void command(String task,Leader leader) {
leader.doing(task);
}
}
测试代码:
public class Test {
public static void main(String[] args) {
new Boss().command("海报图",new Leader());
new Boss().command("爬虫",new Leader());
new Boss().command("卖手机",new Leader());
}
}
JDK的双亲委派机制:
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
synchronized (getClassLoadingLock(name)) {
// First, check if the class has already been loaded
Class<?> c = findLoadedClass(name);
if (c == null) {
long t0 = System.nanoTime();
try {
if (parent != null) {
c = parent.loadClass(name, false);
} else {
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
// ClassNotFoundException thrown if class not found
// from the non-null parent class loader
}
if (c == null) {
// If still not found, then invoke findClass in order
// to find the class.
long t1 = System.nanoTime();
c = findClass(name);
// this is the defining class loader; record the stats
sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
sun.misc.PerfCounter.getFindClasses().increment();
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
}
Method中的invoke方法
@CallerSensitive
public Object invoke(Object obj, Object... args)
throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
MethodAccessor ma = methodAccessor; // read volatile
if (ma == null) {
ma = acquireMethodAccessor();
}
return ma.invoke(obj, args);
}
具体实现类:
class DelegatingMethodAccessorImpl extends MethodAccessorImpl {
private MethodAccessorImpl delegate;
DelegatingMethodAccessorImpl(MethodAccessorImpl var1) {
this.setDelegate(var1);
}
public Object invoke(Object var1, Object[] var2) throws IllegalArgumentException, InvocationTargetException {
return this.delegate.invoke(var1, var2);
}
void setDelegate(MethodAccessorImpl var1) {
this.delegate = var1;
}
}
Spring中的DispatchServlet也用到了委派模式。
通过任务委派能够将一个大型的任务细化,然后通过统一管理这些子任务的完成情况实现任务的跟进,能够加快任务执行的效率。
任务委派模式需要根据任务的复杂程度进行不同的改变,在任务比较复杂的情况下可能需要进行多重委派,容易造成紊乱。