zoukankan      html  css  js  c++  java
  • 1模板方法模式

    模板方法模式

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

    1模板方法模式的定义
    模板方法模式的英文原文是:
    Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template method lets subclasses redefine certain steps of an algorithm whitout changing the algorithm's structure.
    翻译过来就是:
    定义一个操作中的算法框架,进而推迟一些步骤的执行,将其延迟到子类中。模板方法使得子类不改变算法的结构的情况下,而改变算法。(排序算法、查找算法等)

    模板方法涉及到的2个角色:
    • 抽象模板(Abstract Template)角色:该角色定义一个或多个抽象操作,以便让子类实现;这些抽象操作是基本操作,是一个顶级逻辑的组成步骤。还需要定义并实现一个或几个模板方法,这些模板方法一般是具体方法,即一个框架,实现对基本方法的调度,完成固定的逻辑。
    • 具体模板(Concrete Template)角色:该角色实现抽象模板中定义的一个或多个抽象方法,每一个抽象模板角色都可以有人以多个具体模板角色与之对应,而每一个具体模板角色都可以给出这些抽象方法的不同实现,从而使得顶级逻辑的实现各不相同。
    引例
    创建抽象方法类
    AbstractClass.java
    package com.eric.行为型模式.模板方法模式.引例;
    
    /**
     * @author Eric
     * @ProjectName my_design_23
     * @description 抽象方法
     * @CreateTime 2020-12-05 08:52:29
     */
    public abstract class AbstractClass {
        //基本方法
        protected abstract void operation();
        //模板方法
        public void templateMethod()
        {
            //调用基本方法,完成相关的逻辑
            this.operation();
        }
    }
    创建模板方法的实现类
    ConcreteClass.java
    package com.eric.行为型模式.模板方法模式.引例;
    
    /**
     * @author Eric
     * @ProjectName my_design_23
     * @description 具体模板方法
     * @CreateTime 2020-12-05 08:54:45
     */
    public class ConcreteClass extends AbstractClass {
        //实现基本业务方法
        @Override
        protected void operation() {
            //业务逻辑
            System.out.println("具体的业务逻辑实现方法。");
        }
    }
    创建测试类
    Client.java
    package com.eric.行为型模式.模板方法模式.引例;
    
    /**
     * @author Eric
     * @ProjectName my_design_23
     * @description 测试类
     * @CreateTime 2020-12-05 08:56:06
     */
    public class Client {
        public static void main(String[] args) {
            AbstractClass concreteClass = new ConcreteClass();
            //调用模板方法
            concreteClass.templateMethod();
        }
    }
    测试结果

    2模板方法模式的应用
    a.模板方法模式的优点
    • 封装不变的部分,扩展可变的部分。不变的部分封装到父类中实现,而可变的部分则可通过继承进行扩展。
    • 提取公共部分代码,便于维护。将公共部分的代码抽取出来放在父类中,维护时只需要修改父类中的代码。
    • 行为由父类控制,子类实现。模板方法模式中的基本方法是由子类实现的,因此子类可以通过扩展增加相应的功能,符合开闭原则。
    b.模板方法模式的使用场景
    • 多个子类有公共方法,并且逻辑基本相同。
    • 可以把重要的、复杂的、核心的算法设计为模板方法,周边的相关细节功能则由各个子类实现。
    • 重构时,模板方法模式是一个经常使用的模式,将相同的代码抽取到父类中。

    3模板方法实例
    使用模板方法模式,计算银行活期和定期账户的利息。
    由于利息计算是两个步骤:
    1. 确定账户类型,是活期账户,还是定期账户;
    2. 确定利息的百分比。
    这两个基本的方法抽象到模板类Account中,而具体的实现步骤留给具体的模板类,即Account的子类DemandAccount和FixedAccount来实现。
    模拟银行利率计算的类图

    创建抽象模板方法:
    确定账户类型方法、确定利息的抽象方法交给子类实现。模板方法来计算账户利息。
    Account.java
    package com.eric.行为型模式.模板方法模式.例1;
    
    import java.math.BigDecimal;
    
    /**
     * @author Eric
     * @ProjectName my_design_23
     * @description 抽象模板方法,抽象账户类
     * @CreateTime 2020-12-05 12:46:29
     */
    public abstract class Account {
        //账号
        private String username;
        //构造函数
        public Account(String username){
            this.username = username;
        }
    
        //抽象方法,留给子类实现
        //基本方法
        //确定账户类型
        public abstract String getAccountType();
        //确定利息
        public abstract double getAccountRate();
        //根据账户类型和账号确定账户金额
        public  double getAccountMoney(String accountType,String username)
        {
            //模拟从数据库取值
    
            return 3279.0D;
        }
        //模板方法,计算账户利息
        public String  calculateInterest(){
            //获得账户类型
            String accountType = getAccountType();
            //获得比率
            double accountRate = getAccountRate();
            //获得账户余额
            double accountMoney = getAccountMoney(accountType, username);
    
            //账户余额*利率
            return username+"账户的利息为"+accountMoney*accountRate;
        }
    }
    创建定期和活期账户的实现类,并具体实现抽象模板方法。
    DemandAccount.java
    package com.eric.行为型模式.模板方法模式.例1;
    
    /**
     * @author Eric
     * @ProjectName my_design_23
     * @description 活期存款
     * @CreateTime 2020-12-05 13:05:49
     */
    public class DemandAccount extends Account {
        public DemandAccount(String username) {
            super(username);
        }
    
        @Override
        public String getAccountType() {
            return "活期";
        }
    
        @Override
        public double getAccountRate() {
            return 0.005;
        }
    }
    FixedAccount.java
    package com.eric.行为型模式.模板方法模式.例1;
    
    /**
     * @author Eric
     * @ProjectName my_design_23
     * @description 定期(1年)
     * @CreateTime 2020-12-05 13:06:56
     */
    public class FixedAccount extends Account {
        public FixedAccount(String username) {
            super(username);
        }
    
        @Override
        public String getAccountType() {
            return "定期一年";
        }
    
        @Override
        public double getAccountRate() {
            return 0.035;
        }
    }
    创建测试类
    Client.java
    package com.eric.行为型模式.模板方法模式.例1;
    
    /**
     * @author Eric
     * @ProjectName my_design_23
     * @description 测试类
     * @CreateTime 2020-12-05 13:07:49
     */
    public class Client {
        public static void main(String[] args) {
            //活期账户
            Account demandAccount = new DemandAccount("张三");
            System.out.println(demandAccount.calculateInterest());
            // 定期账户
            Account fixedAccount = new FixedAccount("王二麻子");
            System.out.println(fixedAccount.calculateInterest());
    
        }
    }




    只要你不停下来,慢一点也没关系。
  • 相关阅读:
    Oracle-启动和关闭oracle的归档(ARCHIVELOG)模式
    Linux-数据表示方式
    Linux-21-30
    linux-1-10
    自律
    jenkins-修改系统时间
    jenkins-通过ssh username with private key配置节点服务器
    jenkins-slave开机自动启动
    mongodb-mongo使用
    mongodb-centos76yum安装mongodb
  • 原文地址:https://www.cnblogs.com/zyl-0110/p/14205841.html
Copyright © 2011-2022 走看看