1.定义:定义了一个操作中的算法结构,将某些步骤延迟大子类,使得子类可以不改变该算法机构的前提下从新定义该算法中某些特定的步骤
2.UML
3.涉及角色
1.抽象模版:定义了该算法结构具有的行为,行为分为 1.基本行为:该类行为延迟到子类,也就是说子类负责具体的实现 2.模版行为:负责对基本行为的使用并在该处固化具体的使用顺序,即固化逻辑
2.具体模版:抽象模版子类实现基本行为,即重写父类中的基本行为实现具体的逻辑
4.优点
1.封装不变,扩展可变。不可变的行为封装到父类以达到服用的效果。将可变的部分则通过继承来扩展
2.提取公共代码便于维护和复用。将公共代码提取到父类,便于子类的复用。由于公共代码有且只有一份便于维护
3.符合开闭原则。行为有父类负责。父类自定义了相关的行为。具体实现有子类负责
5.缺点
抽象类/接口定义最上层,最一般的行为,实现类负责完成具体的行为。但是抽象模版中定义了部分抽象行为(基本行为),这些基本行为由子类负责实现,通过模版方法执行的结果影响到了父类的结果。也就是子类对父类产生了影响。在复杂项目中会给代码阅读带来难度
6.使用场景
1.多个子类存在共有的方法并且逻辑基本相同
2.可以将核心行为设计为模版方法,周边行为设置为基本行为,在模版方法中固化核心行为的逻辑
3.代码重构将相同的代码抽取到负累
7.Code
抽象模版
//抽象模版基类,该类的定义尽量满足迪米特原则 public abstract class Car { //定义基本操作 protected abstract void start(); protected abstract void addThrottle(); protected abstract void alarm(); protected abstract void stop(); //定义模版方法,该方法中实现了对基本方法的调用,同时固化了逻辑 //定义final防止子类随意重写,也就是说模版方法一旦确定后不允许重写 public final void run() { this.start(); this.addThrottle(); this.alarm(); this.stop(); } }具体模版
public class BWMCar extends Car{ private static final String BWMCAR = "BWM CAR"; @Override protected void start() { System.out.println(BWMCAR + "启动"); } @Override protected void addThrottle() { System.out.println(BWMCAR + "加油门"); } @Override protected void alarm() { System.out.println(BWMCAR + "鸣笛"); } @Override protected void stop() { System.out.println(BWMCAR + "停止"); } } public class AudiCar extends Car{ private static final String BWMCAR = "AUDI CAR"; @Override protected void start() { System.out.println(BWMCAR + "启动"); } @Override protected void addThrottle() { System.out.println(BWMCAR + "加油门"); } @Override protected void alarm() { System.out.println(BWMCAR + "鸣笛"); } @Override protected void stop() { System.out.println(BWMCAR + "停止"); } } 客户端
public class Client { public static void main(String[] args) { //为采用模版方法模式之前,对api的调用重复,优先将这些固化的调用防治到父类中 Car car1 = new BWMCar(); car1.start(); car1.addThrottle(); car1.alarm(); car1.stop(); car1 = new AudiCar(); car1.start(); car1.addThrottle(); car1.alarm(); car1.stop(); System.out.println("使用模版方法之后"); Car car = new BWMCar(); car.run(); car = new AudiCar(); car.run(); } }
通过外部状态控制模版方法中固化的逻辑
UML
抽象模版
//抽象模版基类,该类的定义尽量满足迪米特原则 public abstract class Cars { //定义基本操作 protected abstract void start(); protected abstract void addThrottle(); protected abstract void alarm(); protected abstract void stop(); //定义模版方法,该方法中实现了对基本方法的调用,同时固化了逻辑 //定义final防止子类随意重写,也就是说模版方法一旦确定后不允许重写 public final void run() { this.start(); this.addThrottle(); this.alarm(); if (this.isStop()) { this.stop(); } } //通过该方法接受外部状态,模版方法通过调用该方法来控制具体的逻辑 //该方法有具体的实现并有固定的返回值,因为某些情况下子类不需要重写该方法 protected boolean isStop() { return true; } } 具体模版 public class VWCar extends Cars { private boolean isStop; private static final String BWMCAR = "AUDI CAR"; @Override protected void start() { System.out.println(BWMCAR + "启动"); } @Override protected void addThrottle() { System.out.println(BWMCAR + "加油门"); } @Override protected void alarm() { System.out.println(BWMCAR + "鸣笛"); } @Override protected void stop() { System.out.println(BWMCAR + "停止"); } public boolean isStop() { System.out.println("是否停车:" + this.isStop); return this.isStop; } //接受外部状态,该行为是子类特有的行为,具有可视性,也就是说子类父类无法使用 public void setStop(boolean stop) { this.isStop = stop; } }//该类不接受外部状态,默认使用父类的状态 public class BenzCar extends Cars { private static final String BWMCAR = "BWM CAR"; @Override protected void start() { System.out.println(BWMCAR + "启动"); } @Override protected void addThrottle() { System.out.println(BWMCAR + "加油门"); } @Override protected void alarm() { System.out.println(BWMCAR + "鸣笛"); } @Override protected void stop() { System.out.println(BWMCAR + "停止"); } } 客户端 public class Client { public static void main(String[] args) { //由于方法可见性,客户端依赖具体的实例 VWCar vwCar = new VWCar(); vwCar.setStop(false); vwCar.run(); Cars car = new BenzCar(); car.run(); } }