委派模式和策略模式
委派模式
什么是委派模式?
维基百科对委派模式的解释是:委派模式(delegation pattern)是软件设计模式中的一项基本技巧。在委派模式中,有两个对象参与处理同一个请求,接受请求的对象将请求委托给另一个对象来代理。
委派模式的基本作用就是负责任务的调用和分配任务,跟代理模式很像,可以看做是一种特殊情况下的静态代理的全权代理,但是代理模式注重过程,而委派模式注重结果。委派模式在Spring中应用非常多,大家常用的DispatcherServlet其实就是用到了委派模式。现实生活中也常有委派的场景发生。例如:教室要进行大扫除,老师(Teacher)布置任务给班长(Monitor),班长再根据任务分配给学生(Student),我们以代码的形式进行模拟一下。
/**
* @author: Winston
* @createTime: 2021/6/24
*
* 老师
*/
public class Teacher {
/**
* 给班长下发命令
* @param command
* @param monitor
*/
public void command(String command, Monitor monitor){
monitor.doing(command);
}
}
/**
* @author: Winston
* @createTime: 2021/6/24
* 学生听指令的接口
*/
public interface IStudent {
/**
* 根据指令做事
* @param command
*/
void doing(String command);
}
/**
* @author: Winston
* @createTime: 2021/6/24
*
* 班长
*/
public class Monitor implements IStudent{
/**
* map用来存放接收指令的学生,key是指令 map 是学生
*/
private Map<String,IStudent> studentMap = new HashMap<>();
public Monitor(){
studentMap.put("扫地",new StudentA());
studentMap.put("擦黑板",new StudentB());
}
/**
* 班长不干活,根据指令给学生分派任务
* @param command
*/
@Override
public void doing(String command) {
studentMap.get(command).doing(command);
}
}
/**
* @author: Winston
* @createTime: 2021/6/24
*/
public class StudentA implements IStudent {
@Override
public void doing(String command) {
System.out.println("我是StudentA,我大扫除的职责是,"+command);
}
}
/**
* @author: Winston
* @createTime: 2021/6/24
*/
public class StudentB implements IStudent {
@Override
public void doing(String command) {
System.out.println("我是StudentB,我大扫除的职责是,"+command);
}
}
测试类
/**
* @author: Winston
* @createTime: 2021/6/24
*/
public class DelegateTest {
public static void main(String[] args) {
//客户请求(Teacher)、委派者(Monitor)、被被委派者(Student)
//委派者要持有被委派者的引用
//代理模式注重的是过程, 委派模式注重的是结果
//策略模式注重是可扩展(外部扩展),委派模式注重内部的灵活和复用
//委派的核心:就是分发、调度、派遣
//委派模式:就是静态代理和策略模式一种特殊的组合
new Teacher().command("扫地", new Monitor());
}
}
运行结果:我是StudentA,我大扫除的职责是,扫地
委派模式在SpringMVC源码中的体现
下面我们来简单模拟一下SpringMVC的DispatcherServlet是怎么实现委派模式的。先创建几个Controller
/**
* @author: Winston
* @createTime: 2021/6/24
*/
public class UserController {
public void findUserById(String id){
}
}
/**
* @author: Winston
* @createTime: 2021/6/24
*/
public class OrderController {
public void findOrderById(String id){
}
}
/**
* @author: Winston
* @createTime: 2021/6/24
*/
public class IndexController {
public void index(){
}
}
创建一个DispatcherServlet用于分发请求
/**
* 这个类就相当于是班长角色
* @author: Winston
* @createTime: 2021/6/24
*/
public class DispatcherServlet extends HttpServlet {
private void doDispatcher(HttpServletRequest request, HttpServletResponse response){
String requestURI = request.getRequestURI();
String id = request.getParameter("id");
// 根据uri判断分发请求到Controller
if("findUserById".equals(requestURI)){
new UserController().findUserById(id);
}else if("findOrderById".equals(requestURI)){
new OrderController().findOrderById(id);
}else if("index".equals(requestURI)){
new IndexController().index();
}else {
try {
response.getWriter().write("404 NOT FOUND");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
配置web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:javaee="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<display-name>Gupao Web Application</display-name>
<servlet>