委派模式不属于GoF 23种设计模式。委派模式的基本作用就是负责任务的派遣和调用,跟代理模式很像,可以看成一种特殊情况下的静态的全权代理。但是,代理模式注重过程,委派模式注重结果。委派模式在Spring种的应用场景非常多,我们最熟悉的DispatcherServlet就用到了委派模式。文中会简单模仿下DispatcherServlet的实现。
在现实生活中也常有委派模式的发生场景,如 Boss 给 Leader 下达任务,Leader 会根据实际情况给每个 coder 下发任务,等每个 coder 完成任务之后,leader 再把结果回报给 boss 。在此过程中 boss 只关心任务的完成情况,而不会关注 是哪个 coder 完成的哪个任务。下面就用一个简单的例子来说明委派模式:
1、创建 Employee 接口
public interface Employee {
public void code(String command);
}
2、创建码农A
public class CoderA implements Employee {
@Voerride
public void code(String command){
System.out.println("我是 CodeA ,我工作内容是" + command );
}
}
3、创建码农B
public class CoderB implements Employee {
@Voerride
public void code(String command){
System.out.println("我是 CodeB ,我工作内容是" + command );
}
}
4、创建Leader
public class Leader implements Employee {
// 可以看成任务中心
Map tasks = new HashMap();
public Leader {
tasks.put("加密",new CoderA());
tasks.put("登录",new CoderB());
}
// leader 自己是不干活的,任务或发配给每个 coder
@Voerride
public void code(String command){
tasks.get(command).code(command);
}
}
5、创建BOSS类,下达任务
public class Boss {
// 下达工作指令
public void command(String command,Leader leader){
leader.code(command);
}
}
6、测试结果
public class Test {
public static void main (String[] args){
// 创建 Boss 实例
Boss boss = new Boss();
// 创建 Leader 实例
Leader leader = new Leader();
// 给 Leader 下发任务
boss.command("登录",leader);
}
}
控制台输出:
我是 CodeB ,我的工作内容是登录
由上述的小例子,应该可以看到, Boss 只对 Leader 下达命令,并没有直接给 Code 分配任务,分配任务由 Leader 来做。也就是说 Boss 委派 Leader 来 分配任务。
DispatcherServlet
下面模仿 Spring MVC 中 DispatcherServlet 的实现:
1、先创建一个业务类 MemberController
public class MemberController {
public Object getMemberById(String mid) {
...
}
}
2、创建一个订单类 OrderController
public class OrderController {
public Object getOrderById(String oid) {
...
}
}
3、创建一个 SystemController
public class SystemController {
public Object login() {
...
}
public Object logout() {
...
}
}
4、创建 DispatcherServlet 类
public class DispatcherServlet extends HttpServlet{
public doDispatch(HttpServletRequest request, HttpServletRqsponse response){
// 获取请求地址
String uri = request.getRequestURI();
// 获取请求参数
String id = request.getParameter("id");
if("getMemberById".equals(uri)){
new MemberController().getMemberById(id);
}else if("getOrderById".equals(uri)){
new OrderController().getOrderById(id);
}else if("login".equals(uri)){
new SystemController().login();
}else if("logout".equals(uri)){
new SystemController().logout();
}else{
response.getWriter().write("404 Not Found !");
}
}
protected void service(HttpServletRequest req, HttpServletRqsponse res){
try{
doDispatch(req,res);
}catch(Exception e){
e.printStackTrace();
}
}
}
5、web.xml 中的配置:
servlet
*.DispatcherServlet
1
servlet
/*
以上就实现了 Spring MVC 中分发路由的功能,在真正的框架中的实现肯定不是写死的,而是根据反射获取所有的 uri ,在访问时进行匹配,DispatcherServlet 的功能就是对请求进行分发,路由到对应的方法中。当然在 Spring 中还有很多 委派模式,以 Delegate 结尾的地方都实现了委派模式,有时间可以去了解一下。