package templateMethod;
/**
* @author jiq
* 类型:Behavioral
* 定义: 模板方法在一个方法中定义了一个算法的骨架,而将其中一些步骤的实现延迟到子类中。
* 模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
*
* OO原则:好莱坞原则- 别调用我们,我们会调用你的。
* 在好莱坞,把简历递交给演艺公司后就只有回家等待。由演艺公司对整个娱乐项的完全控制,
* 演员只能被动式的接受公司的差使,在需要的环节中,完成自己的演出。模板方法模式充分的
* 体现了“好莱坞”原则。由父类完全控制着子类的逻辑,子类不需要调用父类,而通过父类来
* 调用子类,子类可以实现父类的可变部份,却继承父类的逻辑,不能改变业务逻辑。
* 开闭原则 - 模板方法模式意图是由抽象父类控制顶级逻辑,并把基本操作的实现推迟到子类
* 去实现,这是通过继承的手段来达到对象的复用,同时也遵守了开闭原则。
*
* 区别: 模版方法封装可互换的行为,然后使用委托来决定要采用哪个行为。
* 策略模式,由子类来决定如何实现算法中的步骤。
* 工厂方法,由子类来决定要实例化哪个具体类。
* 代码说明: 有一个游戏框架,规定了玩游戏的人数,游戏时间,游戏顺序等。
* 我们可以在不改变这个游戏框架的情况下,将具体的游戏实现方式延迟到
* 子类中去。
*/
abstract class Game {
public int playersCount = 0;
//提供给子类实现的抽象方法
abstract void initializeGame();
abstract void makePlay(int player);
abstract boolean endOfGame();
abstract void printWinner();
/**
* 模板方法:定义了一连串的步骤,每个步骤由一个方法代表。
* 将模板方法申明为final防止被覆盖。
*/
final void playOneGame() {
initializeGame();
int j = 0;
while (!endOfGame()){
makePlay(j);
j = (j + 1) % playersCount;
}
printWinner();
hook(); //钩子
}
/**
* 也可以有具体方法,将其申明为final让子类无法覆盖它
* 它可以被模版方法直接使用,也可以被子类使用
*/
public final void otherMethod(){/*...*/}
/**
* 我们也有默认不做事情的方法,称为“钩子”。子类可以
* 视情况决定要不要覆盖它。
*/
void hook() {}
}
//象棋游戏
class Cheese extends Game{
private int count = 0;
void initializeGame() { playersCount = 2; }
void makePlay(int player) {System.out.print(player+" play\n");}
void printWinner() {System.out.print("Winner is XX");}
boolean endOfGame() {
if(count++ > 5) return true;
else return false;
}
}
public class TemplateMethod {
public static void main(String[] args) {
//开始玩游戏
Game game = new Cheese();
game.playOneGame();
}
}