示例

当我们设计一个类时,我们能明确它对外提供的某个方法的内部执行步骤,

但一些步骤,不同的子类有不同的行为时,我们该如何来设计该类?

下面以玩王者荣耀为例展开学习:

玩游戏首先需要初始化游戏,然后加载地图、加载角色、然后才能开始游戏,最后结束游戏

定义一个Game类:

public abstract class Game {

    public final void play () {
initialize();
loadMap();
loadRole();
startPlay();
endPlay();
} /** 初始化游戏 */
protected abstract void initialize(); /** 加载地图 */
protected abstract void loadMap(); /** 加载角色 */
protected abstract void loadRole(); /** 开始游戏 */
protected abstract void startPlay(); /** 结束游戏 */
protected abstract void endPlay();
}

上面类的实现类:

public class KingGlory extends Game {

    @Override
protected void initialize() {
System.out.println("王者荣耀正在初始化,请稍后。。。");
} @Override
protected void loadMap() {
System.out.println("正在加载王者峡谷地图。。。");
} @Override
protected void loadRole() {
System.out.println("正在加载角色鲁班七号。。。");
} @Override
protected void startPlay() {
System.out.println("开始玩王者荣耀。。。");
} @Override
protected void endPlay() {
System.out.println("结束王者荣耀游戏,保存数据。。。");
}
}

测试类:

public class Test {
public static void main(String[] args) {
Game game = new KingGlory();
game.play();
}
}

模板方法模式

定义

一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行

意图

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

主要解决问题

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

适用场景

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

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

优缺点

优点:

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

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

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

缺点:

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

类图:



涉及的角色:

  1. 抽象模板(AbstractTemplate)角色:定义了一个或多个抽象操作,以便让子类实现,这些抽象操作叫基本操作,它们是顶级逻辑的组成步骤;定义并实现了一个模板方法,这个模板方法一般是一个具体方法,它给出了一个顶级逻辑的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类实现
  2. 具体模板(ContrateTemplate)角色:实现父类所定义的一个或多个抽象方法,它们是一个顶级逻辑的组成步骤;每一个抽象模板角色都可以有任意多个具体模板角色与之对应,而每一个具体模板角色都可以给出这些抽象方法的不同实现,从而使得顶级逻辑的实现各不相同

对应源码:

public abstract class AbstractTemplate {

    public void templateMethod() {
doOperation1(); doOperation2(); doOperation3();
} /** 基本方法,由子类实现 */
protected abstract void doOperation1(); /** 基本方法,由子类实现 */
protected abstract void doOperation2(); /** 基本方法,已经实现 */
private final void doOperation3(){
//do something......
}
}
public class ContrateTemplate extends AbstractTemplate {
@Override
protected void doOperation1() {
System.out.println("doOperation1......");
} @Override
protected void doOperation2() {
System.out.println("doOperation2......");
}
}

西天取经的九九八十一难

在《西游记》中,唐僧到西天取经途中所经历的八十一难,说到底,是观音菩萨所控制的一个项目,下面以上面场景为例,写一个小例子:

取经人所经历的劫难,每一步都是菩萨控制好的:

public abstract class LearnFromPeople {

    public final void westernCountry() {
firstHard();
secondHard();
thirdHard();
} /** 第一难 */
protected abstract void firstHard(); /** 第二难 */
protected abstract void secondHard(); /** 第三难 */
protected abstract void thirdHard();
}

唐僧去西天取经,继承了取经人这个抽象类,然后需要历经81难:

public class TangMonk extends LearnFromPeople {
@Override
protected void firstHard() {
System.out.println("金蝉遭贬第一难"); } @Override
protected void secondHard() {
System.out.println("出胎几杀第二难");
} @Override
protected void thirdHard() {
System.out.println("满月抛江第三难");
}
}

唐僧开始上路了:

public class Test {

    public static void main(String[] args) {
LearnFromPeople people = new TangMonk();
people.westernCountry();
}
}



需要注意的是,为了防止恶意的操作,模板方法上面都会加上final关键字

最新文章

  1. Macbook SSD硬盘空间不够用了?来个Xcode大瘦身吧!
  2. swift导航栏导航按钮添加多个按钮事件
  3. iOS版本控制git小结--yoowei
  4. pytest学习笔记(三)
  5. Java面向对象编辑
  6. ios应用内跳转到appstore里评分
  7. AndroidUI 视图动画-混合动画效果 (AnimationSet)/动画效果监听
  8. 小米2S TWRP 3.0.2-0 最新版Recovery
  9. 8个免费实用的C++GUI库
  10. POJ 3258 River Hopscotch(二分查找答案)
  11. 老李分享:为何要使用 Web Services
  12. 友盟分享到微信 监听不执行 监听只执行onStart,(onResult,onError,onCancel 不执行)
  13. Python之matplotlib学习(一)
  14. 基于数据形式说明杜兰特的技术特点的分析(含Python实现讲解部分)
  15. jq demo 九宫格抽奖
  16. Python开发——数据类型【元祖】
  17. oracle登陆认证方式
  18. HTTP 错误 404.0 - Not Found
  19. mysql实现复杂groupby : GROUP_CONCAT
  20. Sql server字段排序,如果字段是字符型的数字

热门文章

  1. Expression #4 of SELECT list is not in GROUP BY clause and contains nonaggregated column
  2. 看完我的笔记不懂也会懂----less
  3. 10. vue之webpack打包详解
  4. 381. O(1) 时间插入、删除和获取随机元素 - 允许重复
  5. [个人总结]利用grad-cam实现人民币分类
  6. RichTextBox FlowDocument类型操作
  7. IDEA修改jar包中class文件后重新生成jar包
  8. Android - Handler原理
  9. vue-cli脚手架安装及注意事项
  10. Hibernate在oracle中ID增长的方式