模板方法模式,指的是在父类或者抽象类中定义算法的框架,将算法因业务不同而不同的核心部分交给子类去实现,父类只关心方法的定义以及执行的顺序,不关心核心方法的具体实现。子类只需要关注核心方法实现,不用关心顺序。
模板方法模式,封装不可变部分,提取公共代码,便于维护和代码复用。由子类或继承类扩展可变部分,容易扩展,符合设计模式六大原则的开闭原则。
这里以银行办理业务为例,去银行取款或者存款,转账,挂失等业务都是不同的业务,但是办理业务都需要先取号,然后排队等待叫号,办理业务,然后对柜员给出评价。其中取号,排队,评价操作可以说对每个人都是一样的,这类操作,我们可以抽取出来放在父类中完成,只有取款、存款、转账、挂失等具体业务操作会有所不同,这些放到子类中完成。
根据这个模型,我们给出如下代码:
BankService.java
package com.xxx.design.template;
public abstract class BankService {
public static int number = 0;
public final String business(){
String no = offerNumber();
waiting();
System.out.printf("当前正在办理业务的是:%s。",no);
System.out.println();
return evaluate();
}
public abstract boolean action();
public String offerNumber(){
String no = "A000" + (++number);
System.out.printf("取到号码:%s。",no);
System.out.println();
return no;
}
public String waiting(){
System.out.println("排队等候中。");
return "OK";
}
public String evaluate(){
if(action()){
return "A";
}else{
return "B";
}
}
}
DepositService.java
package com.xxx.design.template;
public class DepositService extends BankService {
@Override
public boolean action() {
//存款,银行最喜欢了
System.out.println("haha,今天有人存钱了。");
return true;
}
}
DrawingService.java
package com.xxx.design.template;
public class DrawingService extends BankService {
@Override
public boolean action() {
//取钱,小额的去atm机上取,大额在柜台取
System.out.println("取钱啊,小额的去atm机上取,大额的在柜台取。");
return false;
}
}
BankMain.java
package com.xxx.design.template;
public class BankMain {
public static void main(String[] args) {
BankService deposit = new DepositService();
BankService drawcash = new DrawingService();
String evaluation = deposit.business();
System.out.println("存款业务结束,评价是:"+evaluation);
evaluation = drawcash.business();
System.out.println("取款业务结束,评价是:"+evaluation);
}
}
运行以上代码,打印信息如下:
至此,模板方法模式就介绍完了,关于模板方法模式,需要指出的是,他的设计缺点是,如果按照业务来区分,每一个不同的业务就需要定义一个新的子类,当不同的业务越来越多,会导致子类个数增加,系统更加复杂。