Spring中使用到的设计模式(二)----模板方法模式

模板方法模式

1. 模板方法模式简介

1.1 简介

在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。这种类型的设计模式属于行为型模式。

1.2 意图

定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

1.3 UML图解

我们将创建一个定义操作的 Game 抽象类,其中,模板方法设置为 final,这样它就不会被重写。Cricket 和 Football 是扩展了 Game 的实体类,它们重写了抽象类的方法。

TemplatePatternDemo,我们的演示类使用 Game 来演示模板模式的用法。

1.4 应用实例

 1、在造房子的时候,地基、走线、水管都一样,只有在建筑的后期才有加壁橱加栅栏等差异。  

 2、西游记里面菩萨定好的 81 难,这就是一个顶层的逻辑骨架。

 3、spring 中对 Hibernate 的支持,将一些已经定好的方法封装起来,比如开启事务、获取 Session、关闭 Session 等,程序员不重复写那些已经规范好的代码,直接丢一个实体就可以保存。

1.5 优缺点

优点:

1、封装不变部分,扩展可变部分。

2、提取公共代码,便于维护。

       3、行为由父类控制,子类实现。

       缺点:

每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。

1.6 主要解决

一些方法通用,却在每一个子类都重新写了这一方法。

1.7 使用场景

 1、有多个子类共有的方法,且逻辑相同。

 2、重要的、复杂的方法,可以考虑作为模板方法。

1.8 注意事项

为防止恶意操作,一般模板方法都加上 final 关键词。

 

2. 模板方法模式的代码实现

2.1 用抽象基类定义框架

/*

 * 抽象基类,为所有子类提供一个算法框架

 * 提神饮料

 */

public abstract class RefreshBeverage {

/*

* 制备饮料的模板方法

* 封装了所有子类共同遵循的算法框架

*/

public final void prepareBeverageTemplate(){

//步骤1 将水煮沸

boilWater();

//步骤2 泡制饮料

brew();

//步骤3 将饮料倒入杯中

pourInCup();

if(isCustomerWantsCondiments()){

//步骤4 加入调味料

addCondiments();

}

}

/*

* Hook, 钩子函数,提供一个默认或空的实现

* 具体的子类可以自行决定是否挂钩以及如何挂钩

* 询问用户是否加入调料

*/

protected boolean isCustomerWantsCondiments() {

return true;

}

private void boilWater() {

System.out.println("将水煮沸");

}

private void pourInCup() {

System.out.println("将饮料倒入杯中");

}

protected abstract void brew();

protected abstract void addCondiments();

}

2.2 具体子类实现延迟步骤

子类1:

/*

 * 具体子类,提供了咖啡制备的具体实现

 */

public class Coffee extends RefreshBeverage {

@Override

protected void brew() {

System.out.println("用沸水冲泡咖啡");

}

@Override

protected void addCondiments() {

System.out.println("加入糖和牛奶");

}

}

子类2:

/*

 * 具体子类,提供了制备茶的具体实现

 */

public class Tea extends RefreshBeverage {

@Override

protected void brew() {

System.out.println("用80度的热水浸泡茶叶5分钟");

}

@Override

protected void addCondiments() {

System.out.println("加入柠檬");

}

@Override

/*

* 子类通过覆盖的形式选择挂载钩子函数

 */

protected boolean isCustomerWantsCondiments(){

return false;

}

}

测试方法:

public class RefreshBeverageTest {

public static void main(String[] args) {

System.out.println("制备咖啡...");

RefreshBeverage b1 = new Coffee();

b1.prepareBeverageTemplate();

System.out.println("咖啡好了!");

System.out.println("\n******************************************");

System.out.println("制备茶...");

RefreshBeverage b2 = new Tea();

b2.prepareBeverageTemplate();

System.out.println("茶好了!");

}

}

2.3 钩子使子类更灵活

钩子函数如上

3. 模板方法模式总结

3.1 模板方法模式总结

3.1.1 模版方法模式的实现要素:

3.1.2 模版方法模式的适用场景

(1)算法或乘坐遵循相似的逻辑;

(2)重构时(把相同的代码抽取到父类中);

(3)重要、复杂的算法,核心算法设计为模版算法;

3.1.3 模版方法模式的优点

(1)封装性好;

(2)复用性好;

(3)屏蔽细节;

(4)便于维护;

3.1.4 模版方法模式的缺点

继承(java中只能使用单继承)

3.2 行业案例分享

通讯运营商处理日志问题:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值