在我们实际开发中,如果一个方法极其复杂,如果我们把所有的逻辑都写在一个方法中,维护起来会非常困难,有些步骤也很难替换。写,所以代码的可扩展性很差。遇到这种情况,就要考虑今天的主角——模板方法模式。1.概念理解模板方法模式的概念很简单。在一个方法中定义一个算法的骨架,将一些步骤延迟到子类中。模板方法允许子类在不改变算法结构的情况下重新定义算法。中的一些步骤。既然概念叫做“骨架”,那么理所当然地定义了一个抽象类,这就是模板方法模式的第一个角色——抽象模板角色,必须有一个延迟子类来实现骨架方法,这是模板方法的第二个角色——Concretetemplateroles。抽象模板作用:定义一个或多个抽象操作供子类实现。这些抽象操作称为基本操作,它们是顶层逻辑的组成步骤,定义和实现模板方法。具体模板作用:实现父类定义的一个或多个抽象方法,是一个顶层逻辑的组成步骤。每个抽象模板角色都可以有任意数量的具体模板角色与之对应。2.案例实现在我们的业务开发中,往往需要很多对象和方法,而且大部分对象都存在依赖关系。如果我们手动创建和管理对象,是极其困难的。如果我们用工厂模式来创建对象,用一个容器来管理对象,那么再次使用起来就变得异常简单。在“这个过程”中创建对象是一个非常复杂的算法,而且创建对象的方式往往并不单一。我们需要考虑更换算法。这时候,我们可以使用模板方法模式。假设有两种创建对象的方式,一种是基于注解,一种是基于xml,我们将这个方法定义为模板方法,让子类基于注解和xml来实现。我们用refresh()方法来表示这个复杂的过程,应该包括:①开始工作前的预处理;②创建管理对象的容器(模板方法,基于注解,基于XML交给子类实现);③模板方法(交给子类方便扩展);④其他方式(容器刷新后、国际化、应用监控、发布事件等)。我们基于模板方法模式实现了一个简单的demo。抽象模板角色:我们实现了抽象模板角色中的部分逻辑,对象创建容器的obtainFreshBeanFactory()方法交给子类实现,onRefresh()空方法交给子类实现易于扩展。/***抽象模板角色*@authortcy*@Date28-09-2022*/publicabstractclassAbstractApplicationContext{/***案例中容器和对象创建的全过程*/publicvoidrefresh(){this.prepareRefresh();this.obtainFreshBeanFactory();这个.onRefresh();}protectedvoidprepareRefresh(){System.out.println("我用它来进行开始工作前的预处理...");}protectedvoidobtainFreshBeanFactory(){System.out.println("我用来创建默认管理对象的容器...");}/***模板方法,子类实现【springboot实现了,有兴趣可以研究一下】*/protectedvoidonRefresh(){}protectedvoidotherMethod(){System.out.println("容器刷新后、国际化、应用监控、发布事件等等,一堆东西");}}特定模板基于角色的注解为管理对象创建容器/***特定模板基于角色的注解*@authortcy*@Date28-09-2022*/publicclassApplicationContextAnnotationextendsAbstractApplicationContext{@OverrideprotectedvoidobtainFreshBeanFactory(){System.out.println("这是一个基于注解的创建对象容器...");}}具体模板作用——根据xml/**创建管理对象容器*具体模板作用——基于xml*@authortcy*@Date28-09-2022*/publicclassApplicationContextXmlextendsAbstractApplicationContext{@OverrideprotectedvoidobtainFreshBeanFactory(){System.out.println("这是创建对象容器的XML...");}}Client-模拟容器启动过程:/***容器启动过程*@authortcy*@Date28-09-2022*/publicclassClient{publicstaticvoidmain(String[]args){//基于xmlApplicationContextXmlapplicationContextXml=newApplicationContextXml();applicationContextXml.refresh();//基于注解的ApplicationContextAnnotationannotation=newApplicationContextAnnotation();注解.refresh();}}我用它来做开始工作前的预处理...这是创建xml的对象容器...容器刷新后,国际化,应用到监控,发布事件等等一堆东西我用来做预处理开始工作之前...这是基于注解创建一个对象容器...容器刷新、国际化、应用监控、事件发布等之后,稍微了解一下Spring源码的同学大概已经知道一个很多东西。我们的案例是一个简单版的Spring的Refresh()方法,Refresh()方法是Spring的核心方法,Spring良好的扩展性离不开模板方法模式的使用。下图为Spring核心Refresh()方法的执行过程注解。在我们的例子中,onRefresh()的空方法实际上是由Springboot实现的。onRefresh()方法调用Tomcat的jar包启动,这也是Springboot不需要手动注入Tomcat的原因。相信通过这个案例的了解,大部分同学不仅能很好的理解模板方法模式,还能对Spring的启动流程有一个大概的了解。3.总结模板方法应用场景太普遍了。在实际开发中,存在多个子类共享的方法,逻辑是一样的。您可以考虑使用模板方法模式。面对重要复杂的算法时,也可以将核心算法设计成模板方法模式,相关细节由各个子类实现。模板方法具有突出的优点:封装不变部分,扩展可变部分;提取常用代码,方便维护;该行为由父类控制并由子类实现。模板方法的缺点是显而易见的。当方法实现过多时,每个不同的实现都需要一个子类来实现,这势必会导致类的数量增加,使系统变得更大。个人独立开发的应用框架Mango管理系统后台,支持前后端代码生成,支持字段注解等实用开发功能,已全部开源。有兴趣的同学可以点个星号鼓励一下。这是芒果管理系统的前端。设计模式的研究应该是系统的。我推荐你阅读我过去发表的设计模式文章。1.设计模式概述2.设计模式的工厂方法和抽象工厂3.设计模式的单例和原型4.设计模式的建造者模式5.设计模式的代理模式6.设计模式的适配器模式7.设计模式的桥梁设计模式模式八、组合模式九、设计模式装饰器模式十、设计模式外观模式十一、外观模式享元模式十二、设计模式责任链模式十三、设计模式命令模式十四、设计解释器模式设计模式十五、迭代器模式设计模式十六、设计模式中间模式十七、设计模式备忘录模式十八、设计模式观察者模式十九、设计模式状态模式二十、设计模式策略模式
