当前位置 : 主页 > 编程语言 > java >

Java设计模式之模板方法模式

来源:互联网 收集:自由互联 发布时间:2023-01-30
在我们实际开发中,如果一个方法极其复杂时,如果我们将所有的逻辑写在一个方法中,那维护起来就很困难,要替换某些步骤时都要重新写,这样代码的扩展性就很差,当遇到这种情

在我们实际开发中,如果一个方法极其复杂时,如果我们将所有的逻辑写在一个方法中,那维护起来就很困难,要替换某些步骤时都要重新写,这样代码的扩展性就很差,当遇到这种情况就要考虑今天的主角——模板方法模式。

一、概念理解

模板方法模式的概念很简单,在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中,模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。

既然概念叫“骨架”,那想当然的就是定义一个抽象类,这是模板方法模式的第一个角色——抽象模板角色,要有延迟子类实现骨架方法,这是模板方法的第二个角色——具体模板角色。

抽象模板角色:定义了一个或多个抽象操作,以便让子类实现。这些抽象操作叫做基本操作,它们是一个顶级逻辑的组成步骤,定义并实现了一个模板方法。

具体模板角色:实现父类所定义的一个或多个抽象方法,它们是一个顶级逻辑的组成步骤。每一个抽象模板角色都可以有任意多个具体模板角色与之对应。

二、案例实现

在我们的业务开发中往往都需要很多对象、很多方法,对象间也大都存在依赖关系,如果我们手动创建、管理对象就是一件极其困难的事。

如果我们使用工厂模式用于创建对象,使用一个容器用于管理对象,那么再使用起来就变得极其简单了。

在“这个过程”中创建对象就是一个很复杂的算法,而且创建对象的方式往往也不是单一的,我们要考虑能替换算法,这时候就可以使用模板方法模式。

假设创建对象有两种方式,一种是基于注解,一种是基于xml,我们就将该方法定义为一个模板方法,基于注解和基于xml让子类去实现。

我们用refresh()方法代表这个复杂的过程,在这个过程中应该包括:

①开始工作前的预处理;

②创建管理对象的容器(模板方法,基于注解和基于XML交给子类实现);

③模板方法(交给子类,方便扩展);

④其他方法(容器刷新后、国际化、应用监听、发布事件,等等等一堆事)。

我们基于模板方法模式我们实现简单的demo。

抽象模板角色:

我们在抽象模板角色中实现部分逻辑,而创建对象的容器obtainFreshBeanFactory()方法交给子类实现,onRefresh()空方法交给子类实现便于扩展。

/**
 * 抽象模板角色
 * @author tcy
 * @Date 28-09-2022
 */
public abstract class AbstractApplicationContext {

    /**
     * 案例中容器和对象的创建全过程
     */
    public void refresh(){

        this.prepareRefresh();

        this.obtainFreshBeanFactory();

        this.onRefresh();
    }

    protected void prepareRefresh(){
        System.out.println("我用于开始工作前的预处理...");
    }

    protected void obtainFreshBeanFactory(){
        System.out.println("我用于创建默认管理对象的容器...");
    }

    /**
     * 模板方法,子类去实现[springboot实现了他,感兴趣具体可以研究一下]
     */
    protected void onRefresh() {
    }


    protected void otherMethod(){
        System.out.println("容器刷新后、国际化、应用监听、发布事件,等等等,一堆事");
    }
}

具体模板角色-基于注解创建管理对象的容器

/**
 * 具体模板角色-基于注解
 * @author tcy
 * @Date 28-09-2022
 */
public class ApplicationContextAnnotation extends AbstractApplicationContext {
    @Override
    protected void obtainFreshBeanFactory() {
        System.out.println("这是基于注解的创建对象容器...");
    }
}

具体模板角色-基于xml创建管理对象的容器

/**
 * 具体模板角色-基于xml
 * @author tcy
 * @Date 28-09-2022
 */
public class ApplicationContextXml extends AbstractApplicationContext {
    @Override
    protected void obtainFreshBeanFactory() {
        System.out.println("这是xml的创建对象容器...");
    }
}

客户端-模拟容器启动过程:

/**
 * 容器启动过程
 * @author tcy
 * @Date 28-09-2022
 */
public class Client {
    public static void main(String[] args) {

		//基于xml方式
        ApplicationContextXml applicationContextXml = new ApplicationContextXml();
        applicationContextXml.refresh();

		//基于注解方式
        ApplicationContextAnnotation annotation=new ApplicationContextAnnotation();
        annotation.refresh();

    }
}

我用于开始工作前的预处理...
这是xml的创建对象容器...
容器刷新后、国际化、应用监听、发布事件,等等等,一堆事
我用于开始工作前的预处理...
这是基于注解的创建对象容器...
容器刷新后、国际化、应用监听、发布事件,等等等,一堆事

对Spring源码稍微有点了解的同学大概已经知道,我们案例实现的正是简易版的Spring的Refresh()方法,Refresh()方法是Spring最核心的方法,Spring良好的扩展性正是离不开模板方法模式的运用。下图为Spring核心Refresh()方法的执行大流程注释。

在我们案例中的onRefresh()的空方法,实际中Springboot就是实现了这个空方法,onRefresh()方法调用了Tomcat的jar包启动,这也是Springboot不需要手动注入Tomcat的原因。

相信通过这个案例的理解,大部分同学不仅能很好的理解模板方法模式,想必对Spring的启动过程也有了一个大概的了解。

三、总结

模板方法应用场景太普遍了,在实际开发中有多个子类共有的方法,并且逻辑相同,可以考虑使用模板方法模式。当面对重要、复杂的算法,也可以把核心算法设计为模板方法模式,相关细节则由各个子类实现。

模板方法优点突出:封装不变部分,扩展可变部分;提取公共代码,便于维护;行为由父类控制,子类实现。

模板方法的缺点很明显,当方法实现过多的时候,每一个不同的实现都需要一个子类来实现,这必然导致类的个数增加,使得系统变得更加庞大。

到此这篇关于Java设计模式之模板方法模式的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持自由互联。

上一篇:远程调用@FeignClient注解属性使用详解
下一篇:没有了
网友评论