博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式-模板方法模式(15)
阅读量:6643 次
发布时间:2019-06-25

本文共 3590 字,大约阅读时间需要 11 分钟。

 行为型模式(Behavioral Pattern)是对不同的对象之间划分责任和算法的抽象化。行为型模式包括11种模式:模板方法模式、命令模式、责任链模式、策略模式、迭代器模式、中介者模式、观察者模式、备忘录模式、访问者模式、状态模式、解释器模式。

定义

 模板方法模式(Template Method Pattern)是一种简单的、常见的且应用非常广泛的模式。

 模板方法模式的英文原话是: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.

 翻译:定义一个操作中的算法框架,将一些步骤延迟到子类中,使得子类可以在不改变算法结构的前提下即可重新定义该算法的某些特定步骤。

   角色:

 抽象模板(Abstract Template)角色:该角色定义一个或多个抽象操作,以便让子类实现。这些抽象操作是基本操作,是一个顶级逻辑的组成步骤。还需要定义并实现一个或几个模板方法,这些模板方法一般是具体方法,即一个框架,实现对基本方法的调度,完成固定的逻辑。

 具体模板(Concrete Template)角色:该角色实现抽象模板中定义的一个或多个抽象方法,每一个抽象模板角色都可以有任意多个具体模板角色与之对应,而每一个具体模板角色都可以给出这些抽象方法的不同实现,从而使得顶级逻辑的实现各不相同。

/** * 抽象模板角色 */public abstract class AbstractClass {    //基本方法    protected abstract void operation();    //基本方法2    protected abstract void operation2();        //模板方法    public void templateMethod(){        //调用基本方法,完成相关逻辑        this.operation();        this.operation2();    }}/** * 具体模板角色 */public class ConcreteClass extends AbstractClass{    //实现基本业务方法    @Override    protected void operation() {        //业务逻辑        System.out.println("具体类的操作");    }    @Override    protected void operation2() {        //业务逻辑        System.out.println("具体类的操作2");    }}public class Client {    public static void main(String[] args) {        AbstractClass ac = new ConcreteClass();        //调用模板方法        ac.templateMethod();    }}

模板方法调用基本方法后结果如下:

优点

 封装不变的部分,扩展可变的部分。将不变的部分封装到父类中实现,而可变的部分则可以通过继承进行扩展。

 提取公共部分代码,便于维护。将公共部分的代码抽取出来放在父类中,维护时只需修改父类中的代码。

 行为由父类控制,子类实现。模板方法模式中的基本方法是由子类实现的,因此子类可以通过扩展增加相应的功能,符合开闭原则。

应用场景 

 多个子类有公共方法,并且逻辑基本相同时。

 可以把重要的、复杂的核心算法设计为模板方法,周边的相关细节功能则由各个子类实现。

 重构时,模板方法模式是一种经常使用的模式,将相同的代码抽取出来放到父类中。 

   事务就用到了这个设计模式,前置增强,后置增强都延迟到子类中去

计算银行利息Demo

/** * 抽象模板,抽象账户类 */public abstract class Account {    //账号    private String accountNumber;    //构造函数    public Account(){        accountNumber = null;    }    public Account(String accountNumber) {        this.accountNumber = accountNumber;    }    /**     * 基本方法,确定账户类型,留给子类实现     * @return     */    protected abstract String getAccountType();    /**     * 基本方法,确定利息,留给子类实现     * @return     */    protected abstract double getInterestRate();    /**     * 基本方法,根据账户类型和账户确定账户金额     * @param accountType     * @param accountNumber     * @return     */    public double calculateAmount(String accountType,String accountNumber){        //访问数据库...此处直接返回账户金额        return 10000.00D;    }    //模板方法,计算账户利息    public double calculateInterest(){        String accountType = getAccountType();        double interestRate = getInterestRate();        double amount = calculateAmount(accountType,accountNumber);        return amount*interestRate;    }}/** * 具体模板类,活期账户 */public class DemandAccount extends Account {    @Override    protected String getAccountType() {        return "活期";    }    @Override    protected double getInterestRate() {        return 0.003D;    }}/** * 具体模板类,定期账户 */public class FixedAccount extends Account {    /**     * 基本方法,确定账户类型     * @return     */    protected String getAccountType() {        return "一年定期";    }    /**     * 基本方法,确定利息     * @return     */    protected double getInterestRate() {        return 0.04D;    }}/** * 测试类 */public class ClientAccount {    public static void main(String[] args) {        Account account = new DemandAccount();        System.out.println("活期账户利息:"+account.calculateInterest());        account = new FixedAccount();        System.out.println("一年定期账户利息:"+account.calculateInterest());    }}

运行结果:

转载于:https://www.cnblogs.com/aeolian/p/8872293.html

你可能感兴趣的文章
SQLServer 数据库镜像+复制切换方案
查看>>
ThoughtWorks代码挑战——FizzBuzzWhizz
查看>>
异常相关问题
查看>>
无法定位序数XX于动态链接库XX.dll的解决的方法
查看>>
企业服务总线Enterprise service bus介绍
查看>>
使用fuser命令kill一个终端(特殊文件)的方法
查看>>
oc-15-self
查看>>
高速充电技术介绍
查看>>
RestTemplate
查看>>
三、jdk工具之jstack(Java Stack Trace)
查看>>
树莓派 Windows10 IoT Core 开发教程
查看>>
微信网页版朋友圈在哪?怎么找不到
查看>>
Codeforces #263 div2 解题报告
查看>>
nginx 代理https后,应用redirect https变成http --转
查看>>
poj 2406 Power Strings 周期问题
查看>>
SNF快速开发平台成长史V4.5-Spring.Net.Framework-SNF软件开发机器人
查看>>
工作日志2014-08-21
查看>>
iOS-UIImageView载入网络下载的图片(异步+多线程)
查看>>
python3 tkinter
查看>>
haproxy(8):haproxy代理MySQL要考虑的问题
查看>>