一、前言
说起来设计模式,大家应该都耳熟能详,设计模式代表了软件设计的最佳实践,是经过不断总结提炼出来的代码设计经验的分类总结,这些模式或者可以简化代码,或者可以是代码逻辑开起来清晰,或者对功能扩展很方便…。
设计模式按照使用场景可以分为三大类:创建型模式(Creational Patterns)、结构型模式(Structural Patterns)、行为型模式(Behavioral Patterns)。
创建型模式(Creational Patterns)
对对象的实例化过程进行抽象,这使得一个系统可以不用关心这些对象是如何创建,组合,呈现的,对于类创建模式来说通过使用继承改变实例化的类,对于对象创建模式来说通过使用代理来实例化所需要的对象。
结构型模式(Structural Patterns)
通过对多个类和对象进行组合得到复杂结构的类,一般使用继承继承或者成员变量引用形式来实现。
行为型模式(Behavioral Patterns)
行为模式不仅表达了对象和类,还表达了他们之间的交互,涉及到了对象和算法的分配。
下面就带大家看下开源框架框架中是如何应用这些经典设计模式的。
二、责任链设计模式(Chain of Responsibility Pattern)
2.1 介绍
责任链模式是把多个对象串联起来形成一个链状结构,让每个对象都有机会对事件发送者的请求进行处理。责任链模式是设计模式中的行为模式,设计意图是为了使事件发送者和事件接受者之间解耦。通常责任链链中的每个对象都有下一个对象的引入(例如tomcat 里面StandardPipeline用来管理valve),或者有个同一个链管理工厂里面使用数组存放了所有的对象(例如tomcat里面ApplicationFilterChain用来关系filter)。
2.2 Tomcat中Valve链
Tomcat中StandardEngine,StandardHost,StandardContext里面都有自己StandardPipeline,下面以StandardEngine里面StandardPipeline为例讲解
image.png
从上面类图可知道每个Valve都要继承ValveBase类,该类里面有一个Valve的引用,实际是链中下一个节点对象,Valve就是通过每个Valve里面的next串联为链的。
每个valve的invoke方法里面调用next.invoke激活链中下一个节点,并且StandardEngine,StandardHost,StandardContext都有一个basic valve这个valve在链的末尾用来激活子容器的valve链。
2.3 Tomcat中Filter链
Tomcat中Filter链是使用ApplicationFilterChain来管理的,具体结构如下图:
可知Filter链不是像Valve一样在内部维护下个节点的引用,而是在ApplicationFilterChain中搞了个数组存放所有的Filter,并通过n统计Filter总个数,pos是当前filter的下标。
ApplicationFilterChain的doFilter代码如下:
public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException { ... internalDoFilter(request,response); ... }private void internalDoFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException { // Call the next filter if there is one if (pos < n) { //获取filter链中下标为pos的filter ApplicationFilterConfig filterConfig = filters[pos++]; Filter filter = null; try { filter = filterConfig.getFilter(); support.fireInstanceEvent(InstanceEvent.BEFORE_FILTER_EVENT, filter, request, response); if (request.isAsyncSupported() && "false".equalsIgnoreCase( filterConfig.getFilterDef().getAsyncSupported())) { request.setAttribute(Globals.ASYNC_SUPPORTED_ATTR, Boolean.FALSE); } ... //调用自定义filter的dofilter方法 filter.doFilter(request, response, this); support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT, filter, request, response); } .... } .....}
注:这两种方式的区别是啥,就是说那些场景下使用2.2,什么情况下使用2.3这个目前还没有搞清楚有
知道的麻烦在本帖留言帮我解惑下^^
2.4 使用场景
当一个请求需要
根据请求参数的不同由不同对象来处理时候。
当一个请求需要固定对象顺序处理,并且可扩展性的在固定顺序里面插入新的对象进行处理时候。
三、工厂模式(Factory Pattern)
3.1 介绍
工厂模式是创建型模式,他封装了对象的创建过程,调用者使用具体的工厂方法根据参数就可以获取对应的对象。
3.2 Spring框架中BeanFactory
如图BeanFactory接口提供了getBean方法,在AbstractBeanFactory中实现了该方法,经过层层继承,实现,最后DefaultListableBeanFactory实现了BeanDefinitionRegistry接口用来保存bean定义,继承了AbstractAutowireCapableBeanFactory用来支撑autowired。
一个例子
@Testpublic void testBeanFactoy() throws NamingException, SQLException, ParseException, IOException { //创建Bean工厂 DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); //给bean工厂添加bean定义,解析xml里面的bean放入bean工厂 loadBeanDefinitions(bf); //根据名字从bean工厂获取bean Hello hello = (Hello) bf.getBean("hello"); hello.sayHello(); Hello2 hello2 = (Hello2) bf.getBean("hello2"); hello2.sayHello();}protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws IOException { XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); String[] configLocations = new String[] { "beans2.xml" }; if (configLocations != null) { beanDefinitionReader.loadBeanDefinitions(configLocations); }}
3.3 使用场景
不同条件下创建不同实例,用于统一管理bean
不同条件下调用不同工厂方法获取不同场景下的bean
总结
设计模式中每一个模式都描述了在我们工作中不断重复发生的问题,以及问题的解决方案,所以真正掌握设计模式可以避免我们做不必要的重复劳动。如果你在学习Java的过程中或者在工作中遇到什么问题都可以来群里提问,阿里Java高级大牛直播讲解知识点,分享知识,多年工作经验的梳理和总结,带着大家全面、科学地建立自己的技术体系和技术认知!JAVA学习交流QQ群:288351179可以加群找我要课堂链接 注意:是免费的 没有开发经验误入哦! 非喜勿入!
网友评论