一、什么是委派模式

委派模式,是指什么呢?从字面含义理解,委派就是委托安排的意思,委派模式就是在做具体某件事情的过程中,交给其他人来做,这个事件就是在我的完整链路上的一部分,但是复杂度较高的情况下或者我不想做的情况下,完全可以委派给另一个类来处理,只要这个结果是符合我的预期的就可以(相当于填空)。

模板模式与委派模式的区别:模板模式更关注步骤,公共部分会放在模板的骨架步骤中完成,针对子类可能会有特殊的一些操作就可以在特定步骤中重新实现,从模板模式中能够看到清晰的过程步骤。

代理模式与委派模式的区别:代理模式就是这个事情就根本不是我做的,但是我只能提供其中关键的一些信息,其他的周边或者在此基础上的扩展都可以交给其他人来做,完整的一个问题,能够得到解决(这是目前理解到的代理模式,后续如果有更新,会重新对这里进行修改)

二、Spring中的应用

(一)   iOC相关部分中,在进行对象实例化的过程有用到委派模式?

在doRegisterBeanDefinitions()即BeanDefinition进行注册的过程中,会设置BeanDefinitionParserDelegate类型的Delegate对象传给this.delegate,并将这个对象作为一个参数传给:parseBeanDefinitions(root, this.delegate)中,然后主要的解析的工作就是通过delegate作为主要角色来完成的,可以看到下方代码:

/**

 * Parse the elements at the root level in the document:

 * "import", "alias", "bean".

 * @param root the DOM root element of the document

 */

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {

   //判断节点是否属于同一命名空间,是则执行后续的解析

   if (delegate.isDefaultNamespace(root)) {

      NodeList nl = root.getChildNodes();

      for (int i = 0; i < nl.getLength(); i++) {

         Node node = nl.item(i);

         if (node instanceof Element) {

            Element ele = (Element) node;

            if (delegate.isDefaultNamespace(ele)) {

               parseDefaultElement(ele, delegate);

            }

            else {

               //注解定义的Context的nameSpace进入到这个分支中

               delegate.parseCustomElement(ele);

            }

         }

      }

   }

   else {

      delegate.parseCustomElement(root);

   }

}

其中最终能够走到bean注册部分的是,会进入到parseDefaultElement(ele, delegate)中,然后针对不同的节点类型,针对bean的节点进行真正的注册操作,而在这个过程中,delegate会对element进行parseBeanDefinitionElement,得到了一个BeanDefinitionHolder类型的对象,之后通过这个对象完成真正的注册到Factory的操作

(二)   在SpringMVC中,类DispatcherServlet,就是:用于HTTP请求处理程序/控制器的中央调度程序,针对通过WEB UI输入的url请求,委派给DispatcherServlet处理,从委派者的角度来看,关注结果即可

(三)   实际生活的例子:委派可以理解成Leader来做工作,也会做一部分,只是将其中一个部分交给Member来做,Member按照自己的方式做完之后,Leader只关注结果(这是一个两方的关系,代理模式是一个三方的关系,例如房东+中介+租客,中介相对于房东和租客来说,都是代理)。

三、自写demo示例

分别为:Leader类、Member类、StaffdoTask类、StaffInfo类、Task类

其中Task类为:任务类;StaffInfo类:雇员信息类;StaffdoTask类:雇员做任务类;Leader类:组长类(委派者),Member类:组员类(被委派者)

Task类代码如下:

public class Task {
String id;
String name;
String step;
String deadline; public Task(String id, String name, String step, String deadline) {
this.id = id;
this.name = name;
this.step = step;
this.deadline = deadline;
} public String getId() {
return id;
} public String getName() {
return name;
} public String getDeadline() {
return deadline;
} public String getStep() {
return step;
} public void setId(String id) {
this.id = id;
} public void setName(String name) {
this.name = name;
} public void setDeadline(String deadline) {
this.deadline = deadline;
} public void setStep(String step) {
this.step = step;
}
}

StaffInfo类:

public class StaffInfo {
String staffid;
String staffname; public StaffInfo(String staffid, String staffname) {
this.staffid = staffid;
this.staffname = staffname;
} public String getStaffid() {
return staffid;
} public void setStaffid(String staffid) {
this.staffid = staffid;
} public String getStaffname() {
return staffname;
} public void setStaffname(String staffname) {
this.staffname = staffname;
}
}

StaffdoTask接口,Leader类和Member类实现了该接口

public interface StaffdoTask {
public void doTask(StaffInfo staffInfo, Task task);
}

Leader类:

public class Leader{

    //假设Leader的角色为区域销售主管,针对店铺进行人员盘点,将A人员分配到1区,将B人员分配到2区
//店长需要针对区域进行整体管理,包含人员的考勤、日常管理和工作访谈、人员培养等
//其中销售的工作给到不同的区的人员主负责 public void doTask() {
Task task_gongzuofangtan = new Task("1", "工作访谈",
"1、跟进每个区的工作负责人,2、进行访谈交流,3、汇总结果", "20190823");
Task task_kaoqin = new Task("2", "考勤管理", "1、查看每日每人的考勤情况,2、输出考勤报表",
"20190823");
Task[] task_xiaoshou = new Task[3];
Task xiaoshou_1 = new Task("3", "销售", "1、A区域内的人员出售车辆", "2019-0824");
Task xiaoshou_2 = new Task("3", "销售", "1、B区域内的人员出售车辆", "2019-0824");
Task xiaoshou_3 = new Task("3", "销售", "1、C区域内的人员出售车辆", "2019-0824");
task_xiaoshou[0] = xiaoshou_1;
task_xiaoshou[1] = xiaoshou_2;
task_xiaoshou[2] = xiaoshou_3; Task task_huizong = new Task("4", "汇总", "1、将各个区的工作进行整理,2、汇总输出报告", "20190826"); //做自己的工作
doRealTask(task_gongzuofangtan);
doRealTask(task_kaoqin); StaffInfo[] staff_xiaoshou = new StaffInfo[3];
StaffInfo staff_1 = new StaffInfo("1023", "A");
StaffInfo staff_2 = new StaffInfo("1024", "B");
StaffInfo staff_3 = new StaffInfo("1025", "C");
staff_xiaoshou[0] = staff_1;
staff_xiaoshou[1] = staff_2;
staff_xiaoshou[2] = staff_3; doDispatcherTask(task_xiaoshou, staff_xiaoshou); doRealTask(task_huizong);
} public void doRealTask(Task task){
// System.out.println("task info");
System.out.println("taskid:" + task.id + " taskname:" + task.name +
" taskstep:" + task.step + " taskdeadline:" + task.deadline);
} //Desc:进行任务分发处理
public void doDispatcherTask(Task[] tasks, StaffInfo[] staffInfos){
System.out.println("做销售任务的委派");
for (int i = 0; i < tasks.length; i++){
Member member = new Member();
member.doTask(staffInfos[i], tasks[i]);
}
} public static void main(String[] args){
System.out.println("开始工作,并做好任务分派");
Leader leader = new Leader();
leader.doTask();
}
}

Member类:

public class Member implements StaffdoTask{

    @Override
public void doTask(StaffInfo staffInfo, Task task) {
System.out.println("statff " + staffInfo.staffid + "do the task:" + task.id + " " +task.name
+ " " + task.step + " " + task.deadline);
}
}

其中Leader类的main代码运行之后,结果如下:

【Spring源码解析】—— 委派模式的理解和使用的更多相关文章

  1. Spring源码解析 - AbstractBeanFactory 实现接口与父类分析

    我们先来看类图吧: 除了BeanFactory这一支的接口,AbstractBeanFactory主要实现了AliasRegistry和SingletonBeanRegistry接口. 这边主要提供了 ...

  2. spring 源码解析

    1. [文件] spring源码.txt ~ 15B     下载(167) ? 1 springн┤┬вио╬Ш: 2. [文件] spring源码分析之AOP.txt ~ 15KB     下载( ...

  3. Spring源码解析——循环依赖的解决方案

    一.前言 承接<Spring源码解析--创建bean>.<Spring源码解析--创建bean的实例>,我们今天接着聊聊,循环依赖的解决方案,即创建bean的ObjectFac ...

  4. Spring源码解析之ConfigurationClassPostProcessor(二)

    上一个章节,笔者向大家介绍了spring是如何来过滤配置类的,下面我们来看看在过滤出配置类后,spring是如何来解析配置类的.首先过滤出来的配置类会存放在configCandidates列表, 在代 ...

  5. Spring源码解析之八finishBeanFactoryInitialization方法即初始化单例bean

    Spring源码解析之八finishBeanFactoryInitialization方法即初始化单例bean 七千字长文深刻解读,Spirng中是如何初始化单例bean的,和面试中最常问的Sprin ...

  6. Spring源码解析-ioc容器的设计

    Spring源码解析-ioc容器的设计 1 IoC容器系列的设计:BeanFactory和ApplicatioContext 在Spring容器中,主要分为两个主要的容器系列,一个是实现BeanFac ...

  7. Spring源码解析系列汇总

    相信我,你会收藏这篇文章的 本篇文章是这段时间撸出来的Spring源码解析系列文章的汇总,总共包含以下专题.喜欢的同学可以收藏起来以备不时之需 SpringIOC源码解析(上) 本篇文章搭建了IOC源 ...

  8. Spring源码解析之PropertyPlaceholderHelper(占位符解析器)

    Spring源码解析之PropertyPlaceholderHelper(占位符解析器) https://blog.csdn.net/weixin_39471249/article/details/7 ...

  9. Spring源码解析之BeanFactoryPostProcessor(三)

    在上一章中笔者介绍了refresh()的<1>处是如何获取beanFactory对象,下面我们要来学习refresh()方法的<2>处是如何调用invokeBeanFactor ...

  10. Spring源码解析02:Spring IOC容器之XmlBeanFactory启动流程分析和源码解析

    一. 前言 Spring容器主要分为两类BeanFactory和ApplicationContext,后者是基于前者的功能扩展,也就是一个基础容器和一个高级容器的区别.本篇就以BeanFactory基 ...

随机推荐

  1. spring boot 2.x 系列 —— actuator 服务监控与管理

    文章目录 一.概念综述 1.1 端点 1.2 启用端点 1.3 暴露端点 1.4 健康检查信息 二.项目说明 1.1 项目结构说明 1.2 主要依赖 1.3 项目配置 1.4 查看监控状态 三.自定义 ...

  2. 开源joda-time使用demo

    开源joda-time 1.maven中引入 <dependency> <groupId>joda-time</groupId> <artifactId> ...

  3. idea上MyBatis第一个例子

    接着上面创建的maven项目来. 1.java目录下创建cn.happy.entity包 2.idea下创建数据库连接 配置连接参数 3.把数据库表变成实体类 导入成功,改一下包名就可以用了 4.新建 ...

  4. 模拟实现 Tomcat 的核心模块:NIO,HTTP,容器和集群

    如果你想看 Tomcat 源码但又无从入手,不妨从这个项目开始,代码量不多,但包含了 Tomcat 的核心处理流程,并且源码中有相当丰富的注释.相信通过此项目你能了解: NIO 基本编程.HTTP 协 ...

  5. MxNet 模型转Tensorflow pb模型

    用mmdnn实现模型转换 参考链接:https://www.twblogs.net/a/5ca4cadbbd9eee5b1a0713af 安装mmdnn pip install mmdnn 准备好mx ...

  6. POJ 2175:Evacuation Plan(费用流消圈算法)***

    http://poj.org/problem?id=2175 题意:有n个楼,m个防空洞,每个楼有一个坐标和一个人数B,每个防空洞有一个坐标和容纳量C,从楼到防空洞需要的时间是其曼哈顿距离+1,现在给 ...

  7. Java线程池原理浅析

    什么是线程池? 为了避免频繁重复的创建和销毁线程,我们可以让这些线程进行复用,在线程池中,总会有活跃的线程在占用,但是线程池中也会存在没有占用的线程,这些线程处于空闲状态,当有任务的时候会从池子里面拿 ...

  8. flask请求上下文 (转)

    本篇阅读目录 一.flask中的CBV 二.werkzeug + 上下文初步解读 三.偏函数和线程安全 回到顶部 一.flask中的CBV 对比django中的CBV,我们来看一下flask中的CBV ...

  9. scrapy基础知识之 CrawlSpiders爬取lagou招聘保存在mysql(分布式):

    items.py import scrapy class LagouItem(scrapy.Item): # define the fields for your item here like: # ...

  10. jekyll搭建个人博客1

    目录 配置环境 使用模板 配置环境 简介 jekyll是一个简单的免费的,生成静态网页的工具,不需要数据库支持.但是可以配合第三方服务,例如Disqus.最关键的是jekyll可以免费部署在Githu ...