任务交给谁?委派模式告诉你最佳选择!

文章目录

  • 一、概念
  • 二、角色
  • 三、代码实现
  • 四、委派模式在源码中的体现
  • 五、委派模式的优缺点
    • 优点
    • 缺点


一、概念

  1. 委派模式(Delegate Pattern)又叫委托模式,是一种面向对象的设计模式。
  2. 委派模式是一种行为模式,不属于GOF23种设计模式之中
  3. 基本作用是负责任务的调度,是一种特殊的静态代理。

二、角色

抽象任务角色(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也用到了委派模式。

五、委派模式的优缺点

优点

通过任务委派能够将一个大型的任务细化,然后通过统一管理这些子任务的完成情况实现任务的跟进,能够加快任务执行的效率。

缺点

任务委派模式需要根据任务的复杂程度进行不同的改变,在任务比较复杂的情况下可能需要进行多重委派,容易造成紊乱。

你可能感兴趣的:(java,servlet)