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

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

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


介绍

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

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

何时使用:有一些通用的方法。

如何解决:将这些通用算法抽象出来。

关键代码:在抽象类实现,其他步骤在子类实现。

应用实例: 1、在造房子的时候,地基、走线、水管都一样,只有在建筑的后期才有加壁橱加栅栏等差异。 2、西游记里面菩萨定好的 81 难,这就是一个顶层的逻辑骨架。 3、spring 中对 Hibernate 的支持,将一些已经定好的方法封装起来,比如开启事务、获取 Session、关闭 Session 等,程序员不重复写那些已经规范好的代码,直接丢一个实体就可以保存。

优点: 1、封装不变部分,扩展可变部分。 2、提取公共代码,便于维护。 3、行为由父类控制,子类实现

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

使用场景: 1、有多个子类共有的方法,且逻辑相同。 2、重要的、复杂的方法,可以考虑作为模板方法。

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


实现

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

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

这里写图片描述

步骤 1

创建一个抽象类,它的模板方法被设置为 final。

public abstract class Game {   abstract void initialize();   abstract void startPlay();   abstract void endPlay();   //模板   public final void play(){      //初始化游戏      initialize();      //开始游戏      startPlay();      //结束游戏      endPlay();   }}

步骤 2

创建扩展了上述类的实体类。

public class Cricket extends Game {
@Override void endPlay() { System.out.println("Cricket Game Finished!"); } @Override void initialize() { System.out.println("Cricket Game Initialized! Start playing."); } @Override void startPlay() { System.out.println("Cricket Game Started. Enjoy the game!"); }}
public class Football extends Game {
@Override void endPlay() { System.out.println("Football Game Finished!"); } @Override void initialize() { System.out.println("Football Game Initialized! Start playing."); } @Override void startPlay() { System.out.println("Football Game Started. Enjoy the game!"); }}

步骤 3

使用 Game 的模板方法 play() 来演示游戏的定义方式。
用父类去控制行为.子类实现行为.

public class TemplatePatternDemo {   public static void main(String[] args) {      Game game = new Cricket();      game.play();      System.out.println();      game = new Football();      game.play();         }}

关键在于:父类控制行为,子类实现具体行为 这段话.

士兵类:

/**  * @ClassName: Soldier  * @Description: abstract class Soldier  * @author zhangdi      */ public abstract class Soldier {
//作战 void battleWithEnemies(){ wearEquipment(); wearArms(); fight(); } //穿戴装备 void wearEquipment(){ System.out.println("士兵统一穿戴防具.."); } abstract void wearArms();//装配兵器 abstract void fight();//作战}

步兵类:

/**  * @ClassName: Infantry  * @Description: 步兵 * @author zhangdi     */ public class Infantry extends Soldier{
@Override void wearArms() { System.out.println("步兵装配长矛.."); } @Override void fight() { System.out.println("步兵冲锋..."); }}

弓箭手类:

/**  * @ClassName: Archer  * @Description: 弓箭手 * @author zhangdi    */ public class Archer extends Soldier{
@Override void wearArms() { System.out.println("弓箭手装配弓箭.."); } @Override void fight() { System.out.println("弓箭手放箭..."); }}

测试类:

public class SoldierTest {    public static void main(String[] args) {        Soldier infantry = new Infantry();        Soldier archer = new Archer();        infantry.battleWithEnemies();        System.out.println("--------------------");        archer.battleWithEnemies();    }}

输出结果:

士兵统一穿戴防具..步兵装配长矛..步兵冲锋...--------------------士兵统一穿戴防具..弓箭手装配弓箭..弓箭手放箭...

参考:

转载地址:http://uowji.baihongyu.com/

你可能感兴趣的文章
【数据结构周周练】007顺序结构实现完全二叉树操作- 求编号i与j最近公共祖先结点
查看>>
C++ goto语句详解
查看>>
【数据结构周周练】008 二叉树的链式创建及测试
查看>>
【数据结构周周练】009 二叉树的先序、中序、后序遍历(递归算法实现)
查看>>
【数据结构必备基本知识】递归与迭代的联系、区别与优缺点对比详解
查看>>
【数据结构周周练】010 递归算法实现二叉树的创建与遍历
查看>>
【数据结构周周练】011 非递归算法实现二叉树的遍历
查看>>
【数据结构周周练】012 利用队列和非递归算法实现二叉树的层次遍历
查看>>
【数据结构周周练】013 利用栈和非递归算法求二叉树的高
查看>>
【数据结构周周练】014 利用栈和非递归算法求链式存储的二叉树是否为完全二叉树
查看>>
【数据结构周周练】015 利用递归算法创建链式存储的二叉树并转换左右孩子结点
查看>>
【数据结构周周练】016 利用递归算法及孩子兄弟表示法创建树、遍历树并求树的深度
查看>>
【数据结构周周练】017 利用递归算法及孩子兄弟表示法创建森林、遍历森林并求森林的叶子结点个数
查看>>
【数据结构必备基本知识】数据结构常用预定义常量、类型及头文件
查看>>
【数据结构周周练】018 利用递归算法及中序遍历将二叉树线索化并遍历
查看>>
【数据结构周周练】019 利用递归算法创建二叉排序树并遍历
查看>>
【数据结构周周练】020 二叉排序树的排序与迭代查找
查看>>
【数据结构周周练】035 利用递归判断一棵二叉树是否为二叉排序树
查看>>
【数据结构周周练】021 求某一个数据在二叉排序树中的层数
查看>>
【数据结构周周练】022 从大到小输出二叉排序树中小于某个值的所有结点编号及数据
查看>>