委派模式
1:委派模式
在23种设计模式里面是没有委派模式的,但是spring中大量存在,Spring MVC框架中的DispatcherServlet其实就用到了委派模式,我们可以将委派模式理解成静态模式以及策略模式的组合。
2:一个简单的应用场景
分析如下:老板将任务委派给项目经理,项目经理将任务细化,根据每个人擅长的某一方面将细化后的任务分给指定的员工,权衡的方式(策略)有多种,而这个任务项目经理不想干,就将其代理给了各个员工,从这个层面来看委派模式就是策略模式和代理模式的组合。相关类图如下:
3:主要角色
- 客户(Boss)
- 委派者(leader)
- 被委派者(target)
4:主要代码
public interface ITarget {
public void doing(String command);
}
//委派者
public class Leader implements ITarget {
private Map<String,ITarget> targets = new HashMap<String,ITarget>();
//在这里根据策略委派任务
public Leader() {
targets.put("加密",new TargetA());
targets.put("登录",new TargetB());
}
//项目经理自己不干活
public void doing(String command){
targets.get(command).doing(command);
}
}
//被委派者有两个
public class TargetA implements ITarget {
@Override
public void doing(String command) {
System.out.println("我是员工A,我现在开始干" + command + "工作");
}
}
public class TargetB implements ITarget {
@Override
public void doing(String command) {
System.out.println("我是员工B,我现在开始干" + command + "工作");
}
}
//客户
public class Boss {
public static void main(String[] args) {
//客户请求(Boss)、委派者(Leader)、被被委派者(Target)
//委派者要持有被委派者的引用
//代理模式注重的是过程, 委派模式注重的是结果
//策略模式注重是可扩展(外部扩展),委派模式注重内部的灵活和复用
//委派的核心:就是分发、调度、派遣
//委派模式:就是静态代理和策略模式一种特殊的组合
new Leader().doing("登录");
}
}
springmvc 中的委派模式
//被委派角色
public class MemberAction {
public void getMemeberById(String mid){}
}
public class OrderAction {
public void getOrderById(String mid){}
}
----------
public class ServletDispachter {
private List<Handler> handlerMapping = new ArrayList<Handler>();
public ServletDispachter(){
try {
Class<?> memberActionClass = MemberAction.class;
handlerMapping.add(new Handler()
.setController(memberActionClass.newInstance())
.setMethod(memberActionClass.getMethod("getMemberById", new Class[]{String.class}))
.setUrl("/web/getMemberById.json"));
}catch(Exception e){
}
}
public void doService(HttpServletRequest request, HttpServletResponse response){
doDispatch(request,response);
}
private void doDispatch(HttpServletRequest request, HttpServletResponse response){
//1、获取用户请求的url
// 如果按照J2EE的标准、每个url对对应一个Serlvet,url由浏览器输入
String uri = request.getRequestURI();
//2、Servlet拿到url以后,要做权衡(要做判断,要做选择)
// 根据用户请求的URL,去找到这个url对应的某一个java类的方法
//3、通过拿到的URL去handlerMapping(我们把它认为是策略常量)
Handler handle = null;//可以把Handler理解为委派者
for (Handler h: handlerMapping) {
if(uri.equals(h.getUrl())){
handle = h;
break;
}
}
//4、将具体的任务分发给Method(通过反射去调用其对应的方法)
Object object = null;
try {
object = handle.getMethod().invoke(handle.getController(),request.getParameter("mid"));
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
//5、获取到Method执行的结果,通过Response返回出去
// response.getWriter().write();
}
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;
}
}
}