模版方法模型的定义:定义一个操作中的算法的框架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
其中包括:
1、基本方法:由子类实现的方法,并且在模版方法中被调用。
2、模版方法:可以是一个或者几个,一般是一个具体方法,也就是一个框架,实现对基本方法的调度,完成固定的逻辑。
(注意:一般为了防止恶意的操作,模版方法都会加上final关键字,不允许被覆写)
优点:
1、封装不变部分,扩展可变部分。
2、提取公共部分代码,便于维护。
3、行为由父类控制,子类实现。
缺点:
模版方法模式颠倒了我们的设计习惯,抽象类定义了部分抽象方法,由子类实现,子类执行的结果影响了父类的结果,也就是子类对父类产生了影响,这会增加代码阅读的难度。
类图如下:
实现代码如下:
抽象类:
package com.designpatterns.templatemethods; public abstract class HummerModle { protected abstract void start(); protected abstract void stop(); protected abstract void alarm(); protected abstract void engineBoom(); protected void run() { this.start(); this.engineBoom(); if (isAlarm()) { this.alarm(); } this.stop(); } protected boolean isAlarm() { return true; } }
package com.designpatterns.templatemethods; public class HummerOne extends HummerModle { private boolean alarmFlag = true; @Override protected void start() { System.out.println("hummerOne start!"); } @Override protected void stop() { System.out.println("hummerOne stop!"); } @Override protected void alarm() { System.out.println("hummerOne alarm!"); } @Override protected void engineBoom() { System.out.println("hummerOne engineBoom!"); } @Override protected boolean isAlarm() { return this.alarmFlag; } public boolean isAlarmFlag() { return alarmFlag; } public void setAlarmFlag(boolean alarmFlag) { this.alarmFlag = alarmFlag; } }
package com.designpatterns.templatemethods; public class HummerTwo extends HummerModle { @Override protected void start() { System.out.println("hummerTwo start!"); } @Override protected void stop() { System.out.println("hummerTwo stop!"); } @Override protected void alarm() { System.out.println("hummerTwo alarm!"); } @Override protected void engineBoom() { System.out.println("hummerTwo engineBoom!"); } }
package com.designpatterns.templatemethods; import java.util.Scanner; public class Main { public static void main(String[] args) { HummerOne hummerOne = new HummerOne(); String type = new Scanner(System.in).next(); if(type.equals("N")){ hummerOne.setAlarmFlag(false); } hummerOne.run(); HummerTwo hummerTwo = new HummerTwo(); hummerTwo.run(); } }