文档章节

模板方法模式

草原-星空
 草原-星空
发布于 2017/08/03 22:15
字数 992
阅读 3
收藏 0

模板方法模式:定义一个算法中的操作框架,而将一些步骤延迟到子类中。使得子类可以不改变算法的结构即可重定义该算法的某些特定步骤。(Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure)

模板方法模式的通用类图非常简单,仅仅使用了Java的继承机制,但它是一个非常广泛的模式。其类图如下,其中AbstractClass叫做抽象模板,它的方法分为两类: 基本方法:是由子类实现的方法,并且在模板方法被调用。(一般都加上final关键字,防止被覆写) 模板方法:可以有一个或几个,一般是一个具体方法,也就是一个框架,实现对基本方法的调用,完成固定的逻辑。(抽象模板中的基本方法尽量设计为protected类型,符合迪米特法则,不需要暴露的属性或方法尽量不要设置为protected类型。实现类若非必要,尽量不要扩大父类中的访问权限)

输入图片说明

上述通用类图的源码如下:


public abstract class AbstractClass {
    protected abstract void doAnything();
    protected abstract void doSomething();
    public final void templateMethod(){
        /*
         * 调用基本方法,完成相关的逻辑
         */
        this.doAnything();
        this.doSomething();
    }
}
public class ConcreteClass1 extends AbstractClass {

    @Override
    protected void doAnything() {
        // TODO Auto-generated method stub
        //子类实现具体
    }

    @Override
    protected void doSomething() {
        // TODO Auto-generated method stub    
    }
}
public class ConcreteClass2 extends AbstractClass {

    @Override
    protected void doAnything() {
        // TODO Auto-generated method stub
        //子类实现具体
    }

    @Override
    protected void doSomething() {
        // TODO Auto-generated method stub    
    }
}

模板方法模式的优点

封装不变部分,扩展可变部分。把认为不变部分的算法封装到父类中实现,而可变部分的则可以通过继承来继续扩展。 提取公共部分代码,便于维护。 行为由父类控制,子类实现。 模板方法模式的缺点

按照设计习惯,抽象类负责声明最抽象、最一般的事物属性和方法,实现类负责完成具体的事务属性和方法,但是模板方式正好相反,子类执行的结果影响了父类的结果,会增加代码阅读的难度。 模板方法模式的使用场景

多个子类有共有的方法,并且逻辑基本相同 重要、复杂的算法,可以把核心算法设计为模板方法,周边的相关细节功能则由各个子类实现 重构时,模板方法是一个经常使用的方法,把相同的代码抽取到父类中,然后通过构造函数约束其行为。 模板方法模式的扩展

如上通用类图中,若在ConcreteClass2中不想执行doSomething()方法,那么需要对模板方法做一些修改,其通用类图如下:

                                                            ![输入图片说明](https://static.oschina.net/uploads/img/201708/03221537_k7sC.png "在这里输入图片标题")

通用类图的源码如下:


public abstract class AbstractClass {
    protected abstract void doAnything();
    protected abstract void doSomething();
    protected boolean isDoSomething(){ //父类方法返回真
        return true;
    }
    public final void templateMethod(){
        /*
         * 调用基本方法,完成相关的逻辑
         */
        this.doAnything();
        if(this.isDoSomething())
            this.doSomething();
    }
}
public class ConcreteClass1 extends AbstractClass {
    private boolean isDoSth;
    @Override
    protected void doAnything() {
        // TODO Auto-generated method stub
        //子类实现具体
    }

    @Override
    protected void doSomething() {
        // TODO Auto-generated method stub    
    }
    protected void setDo(boolean isDo){
        this.isDoSth = isDo;
    }
    protected boolean isDoSomething(){
        return isDoSth;
    }
}

最佳实践

模板方法模式是通过父类建立框架,子类在重写了父类部分方法之后,在调用从父类继承的方法,产生不同的效果,通过修改子类,影响父类行为的结果,模板方法在一些开源框架中应用非常多,它提供了一个抽象类,然后开源框架写了一堆子类,如果需要扩展功能,可以继承此抽象类,然后覆写protected基本方法,然后在调用一个类似TemplateMethod()的模板方法,完成扩展开发。

© 著作权归作者所有

共有 人打赏支持
草原-星空
粉丝 0
博文 31
码字总数 36144
作品 0
闸北

暂无文章

分布式框架spring-session实现session一致性使用问题

前言:项目中使用到spring-session来缓存用户信息,保证服务之间session一致性,但是获取session信息为什么不能再服务层获取? 一、spring-session实现session一致性方式 用户每一次请求都会...

WALK_MAN
10分钟前
1
0
C++ yield()与sleep_for()

C++11 标准库提供了yield()和sleep_for()两个方法。 (1)std::this_thread::yield(): 线程调用该方法时,主动让出CPU,并且不参与CPU的本次调度,从而让其他线程有机会运行。在后续的调度周...

yepanl
18分钟前
0
0
Java并发编程实战(chapter_3)(线程池ThreadPoolExecutor源码分析)

这个系列一直没再写,很多原因,中间经历了换工作,熟悉项目,熟悉新团队等等一系列的事情。并发课题对于Java来说是一个又重要又难的一大块,除非气定神闲、精力满满,否则我本身是不敢随便写...

心中的理想乡
28分钟前
15
0
shell学习之获取用户的输入命令read

在运行脚本的时候,命令行参数是可以传入参数,还有就是在脚本运行过程中需要用户输入参数,比如你想要在脚本运行时问个问题,并等待运行脚本的人来回答。bash shell为此提 供了read命令。 ...

woshixin
54分钟前
1
0
区块链技术中的那些能商用的企业级应用

WEPOWER是一家立陶宛初创企业,旨在改变可再生电力项目的付费方式。WePower公司创始人Nick Martyniuk表示,政府统一收购价的存在推动了全球风能与太阳能市场的发展。因此,他的公司希望帮助那...

问题终结者
59分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部