您的位置:首页 > 运维架构 > 网站架构

阿里架构师工作十年接触过Java框架设计模式(未完待续)

2018-01-25 16:33 585 查看
一、前言

说起来设计模式,大家应该都耳熟能详,设计模式代表了软件设计的最佳实践,是经过不断总结提炼出来的代码设计经验的分类总结,这些模式或者可以简化代码,或者可以是代码逻辑开起来清晰,或者对功能扩展很方便…。

设计模式按照使用场景可以分为三大类:创建型模式(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可以加群找我要课堂链接 注意:是免费的 没有开发经验误入哦! 非喜勿入!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息