1、委派模式基础介绍
含义:
又叫委托模式,主要目的是将任务的调度和分配与任务的执行分离开来;
它是一种特殊的静态代理,接受请求的对象将请求委托给另一个对象来进行处理;
属于行为型模式;
应用场景:
①委派不知道任务如何进行处理,把请求交给对象处理
②实现程序的解耦(更注重委派的规则)
命名规则:
delegate
生活中的案例:
①老板委派员工实现想法
②业务办理的委托
与代理模式对比:
代理是结构型模式,更关注行为的增强,注重执行过程;
委派则更关注任务的分配,是对命令的执行和任务拆解,而真正干活的是被委派对象,注重执行结果;是特殊的静态代理,相当于单一的全权代理;
门面模式是一种结构型模式,是多重代理;
2、通用实现
行政员工实现打印内容;
行政主管委派行政人员打印一些行政资料;
package Paint;
class AdministrativeStaff{
void print() {
System.out.print("行政人员打印something");
}
}
class Administrator{
AdministrativeStaff staff = new AdministrativeStaff(); // 委派
void print() {
staff.print();
}
}
public class Main {
public static void main(String[] args) {
Administrator administrator= new Administrator();
administrator.print();
}
}
3、开发实例
实例1(老板给主管下达命令,leader分配任务交给不同的员工)
public interface IEmployee{
//干活
void doWork();
}
public class EmployeeA implements IEmployee{
//干活
public void doWork() {
System.out.println("程序员,擅长java,python,c");
}
}
public class EmployeeB implements IEmployee{
//干活
public void doWork() {
System.out.println("产品,擅长ps,axurerp,prd");
}
}
public class Leader{
private IEmployee employeeA;
private IEmployee employeeB;
//干活
public void work(String taskName) {
if("开发".equals(taskName)){
employeeA.doWork()
}else if(){
employeeB.doWork()
}else{
System.out.println("公司没有对应人才");
}
}
}
public class Boss{
private Leader leader = new Leader();
//干活
public void command(String taskName) {
leader.work(taskName);
}
}
缺点: if-else代码不优雅
解决方案:
①使用枚举类
②用策略模式使得可以动态根据任务名获取不同的任务服务;
4、源码中的案例
spring的 ServletDispatcher 中使用
package com.swh.design.delegate.spring;
import com.swh.design.delegate.spring.controller.MemberController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class ServletDispatcher {
// 维护了所有的Controller与uri的映射信息
List<Handler> handlers = new ArrayList<Handler>();
public ServletDispatcher(List<Handler> handlers) {
Class<MemberController> memberControllerClass = MemberController.class;
try {
handlers.add(
new Handler().setController(memberControllerClass.newInstance())
.setMethod(memberControllerClass.getMethod("login",new Class[]{String.class}))
.setUrl("/member/login")
);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
public void doServlet(HttpServletRequest request, HttpServletResponse response){
doDispatcher(request,response);
}
private void doDispatcher(HttpServletRequest request,HttpServletResponse response){
// 获取用户请求的URL
String requestURI = request.getRequestURI();
// 选择需要分发给哪个控制器
Handler handler = null;
for (Handler h : handlers) {
if(handler.url.equals(requestURI)){
handler = h;
break;
}
}
try {
// 执行控制器 让控制器干活
Object aa = handler.method.invoke(handler.controller, request.getParameter("aa"));
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
class Handler {
private Object controller;
private Method method;
private String url;
public Object getController() {
return controller;
}
public Handler setController(Object controller) {
this.controller = controller;
return this;
}
public Method getMethod() {
return method;
}
public Handler setMethod(Method method) {
this.method = method;
return this;
}
public String getUrl() {
return url;
}
public Handler setUrl(String url) {
this.url = url;
return this;
}
}
}
BeanDefiniaionParsentDelegate
java中的
ClassLoader
absract抽象类, parent是父类, 首先考虑父类去加载,没有父类就自己加载(双亲委派)
Method
invoke() 方法 中 ma.invoke(obj,args)
优缺点:
优点:
通过任务委派能够将一个大型的任务细化,然后通过统一管理这些子任务的完成情况实现任务的跟进,
能够加快任务执行的效率;
缺点:
在复杂的任务中,需要进行多重委派,代码复杂度大幅提升,容易造成代码紊乱;