当前位置: 首页 > news >正文

设计模式-行为型模式-模板方法模式

1.模板方法模式定义

        模板方法模式在父类中定义了一个算法的框架,允许子类在不修改结构的情况下重写算法的特定步骤;是一种基于继承的代码服用技术,其结构只存在于父类与子类之间的继承关系下;

1.1 模板方法模式的作用

  • 复用性:所有的子类都可以复用父类中提供的模板方法代码;
  • 扩展性:框架通过模板方法模式提供功能扩展点,让框架用户可以在不修改框架源码的情况下,基于扩展点定制化框架的功能;

1.2 模板方法模式的优缺点

优点

  • 在父类中形式化的定义一个算法,由他的子类来实现细节,子类实现细节并不会改变父类算法中的执行顺序;
  • 模板方法可以实现一种反向的控制结构,通过子类覆盖父类的钩子方法,来决定某一个特定步骤是否需要执行;
  • 在模板方法模式中,可以通过子类来覆盖父类的基本方法,不同的子类可以提供基本方法的不同实现,更换和增加新的子类很方便,符合单一职责原则和开闭原则;

缺点

  •  对每个不同的实现都需要定义一个子类,这会导致系统更加庞大,设计也更加抽象;
  • 父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种返乡的控制结构,提高了代码阅读的难度;

1.3 模板方法模式的使用场景

  • 多个类有相同的方法并且逻辑可以共用时;
  • 将通用的算法或固定流程设计为模板,在每个具体的子类中再继续优化算法步骤或流程时;
  • 重构长代码时,发现某一个经常使用的公共方法;

2.模板方法模式的原理

  • 抽象父类:定义一个算法所包含的所有步骤,并提供一些通用的方法逻辑;
  • 具体子类:继承自抽象父类,根据需要重写父类提供的算法步骤中的某些步骤;

3.模板方法模式实现

【实例】

P2P公司的借款系统中有一个利息计算模块,利息的计算流程是这样的:

  1. 用户登录系统,登录时需要输入账号密码,如果登录失败(比如用户密码错误),系统需要给出提示

  2. 如果用户登录成功,则根据用户的借款的类型不同,使用不同的利息计算方式进行计算

  3. 系统需要显示利息.

【代码】

        抽象父类

/*** 账户抽象类**/
public abstract class Account {//step1 具体方法-验证用户信息是否正确public boolean validate(String account,String password){System.out.println("账号: " + account + ",密码: " + password);if(account.equalsIgnoreCase("tom") &&password.equalsIgnoreCase("123456")){return true;}else{return false;}}//step2 抽象方法-计算利息public abstract void calculate();//step3 具体方法-显示利息public void display(){System.out.println("显示利息!");}//模板方法public void handle(String account,String password){if(!validate(account,password)){System.out.println("账户或密码错误!!");return;}calculate();display();}
}

        具体子类

/*** 借款一个月**/
public class LoanOneMonth extends Account{@Overridepublic void calculate() {System.out.println("借款周期30天,利率为10%!");}
}/*** 借款七天**/
public class LoanSevenDays extends Account{@Overridepublic void calculate() {System.out.println("借款周期7天,无利息!仅收取贷款金额1%的服务费!");}@Overridepublic void display() {System.out.println("七日内借款无利息!");}}

        客户端

public class Client {public static void main(String[] args) {Account a1 = new LoanSevenDays();a1.handle("tom","12345");System.out.println("==========================");Account a2 = new LoanOneMonth();a2.handle("tom","123456");}
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 预训练语言模型的前世今生 - 从Word Embedding到BERT
  • 深入掌握Linux磁盘管理,从入门到精通的完整指南
  • 安装node版本管理工具(nvm)、利用nvm安装node
  • html+css+js网页设计 故宫7个页面 ui还原度100%
  • 解决App推广痛点:一键获取下载数据的秘诀
  • Vue(七) TodoList案例1.0
  • 新的Ubuntu服务器如何启用root账号和配置静态ip以及开启ssh服务
  • spark.sql
  • 数仓基础(九):各大公司实时数仓实践
  • Spring Security与Apache Shiro:Java安全框架的比较
  • 电信500M宽带+AX210无线网卡测速
  • charles使用ssl证书抓包https请求失败解决方案
  • python-简单的dos攻击
  • Flutter之CRC校验
  • Unity编辑器开发 Immediate Mode GUI (IMGUI)
  • php的引用
  • 时间复杂度分析经典问题——最大子序列和
  • [NodeJS] 关于Buffer
  • 11111111
  • CentOS学习笔记 - 12. Nginx搭建Centos7.5远程repo
  • iOS编译提示和导航提示
  • node-glob通配符
  • 前端代码风格自动化系列(二)之Commitlint
  • 为什么要用IPython/Jupyter?
  • 以太坊客户端Geth命令参数详解
  • 用 vue 组件自定义 v-model, 实现一个 Tab 组件。
  • 在 Chrome DevTools 中调试 JavaScript 入门
  • 如何通过报表单元格右键控制报表跳转到不同链接地址 ...
  • ​RecSys 2022 | 面向人岗匹配的双向选择偏好建模
  • ###C语言程序设计-----C语言学习(3)#
  • (Spark3.2.0)Spark SQL 初探: 使用大数据分析2000万KF数据
  • (代码示例)使用setTimeout来延迟加载JS脚本文件
  • (第27天)Oracle 数据泵转换分区表
  • (精确度,召回率,真阳性,假阳性)ACC、敏感性、特异性等 ROC指标
  • (理论篇)httpmoudle和httphandler一览
  • (学习日记)2024.03.12:UCOSIII第十四节:时基列表
  • .htaccess 强制https 单独排除某个目录
  • .java 指数平滑_转载:二次指数平滑法求预测值的Java代码
  • .net core 源码_ASP.NET Core之Identity源码学习
  • .NET Framework 的 bug?try-catch-when 中如果 when 语句抛出异常,程序将彻底崩溃
  • .net快速开发框架源码分享
  • .net中我喜欢的两种验证码
  • @javax.ws.rs Webservice注解
  • @ModelAttribute使用详解
  • @property @synthesize @dynamic 及相关属性作用探究
  • @Query中countQuery的介绍
  • @RequestMapping处理请求异常
  • [Algorithm][动态规划][两个数组的DP][正则表达式匹配][交错字符串][两个字符串的最小ASCII删除和][最长重复子数组]详细讲解
  • [Asp.net mvc]国际化
  • [BZOJ] 2006: [NOI2010]超级钢琴
  • [BZOJ1089][SCOI2003]严格n元树(递推+高精度)
  • [CODE:-5504]没有[SYS.SYSOBJECTS]对象的查询权限
  • [Codeforces] number theory (R1600) Part.11
  • [CSS]CSS 字体属性
  • [C语言]——柔性数组