设计模式之模板方法模式
模板方法模式:定义一个算法中的操作框架,而将一些步骤延迟到子类中。使得子类可以不改变算法的结构即可重定义该算法的某些特定步骤。
通俗来将就是一个固定流程的功能,将公共的流程部分提取到父类中来实现,子类实现其他流程,同时在父类中执行整个流程(也就是说父类中规定了方法的执行流程,而方法的具体实现有子类去决定)。
在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。
这种类型的设计模式属于行为型模式。
场景示例
各个种类的商品有不同的优惠政策,在下单时需要根据优惠政策计算订单金额。
如果不使用模版方法模式,那么通常就是对每个种类的商品写一个优惠计算的方法实现。
但是如果各个种类的商品的其他费用的计算规则一样的,此时每个的计算方法都需要去实现这个方法(当然我们可以将这部分实现单独提取到一个方法,这里直接调用即可);
如果各个计算方法具有关联性(即执行的方法2需要方法1的执行结果),那么一旦这个关联规则发生改变则每个方法都需要去修改;此时就体现出模版方法的优势了。
示例代码
public static void main(String[] args) {
GoodsService fruitService = new FruitService();
fruitService.calculate(10);
System.out.println("======================");
GoodsService homeAppliancesService = new HomeAppliancesService();
homeAppliancesService.calculate(12);
}
interface GoodsService {
/**
* 计算金额
* @param amount 购买数量
*/
void calculate(int amount);
}
/**
* 模板方法实现
*/
static abstract class AbstractGoodsService implements GoodsService {
/**
* 这里设计 计算流程规则
*/
@Override
public void calculate(int amount) {
// 完成通用的逻辑
BigDecimal money = commonCalculate();
// 完成特殊的逻辑
money = money.add(specificCalculate(amount));
System.out.println("共计:"+money);
// 其他操作....
}
private BigDecimal commonCalculate() {
System.out.println("执行公共费用计算:...");
return new BigDecimal("2.00");
}
/**
* 特殊的计算逻辑
* @param amount 购买数量
* @return 返回金额
*/
protected abstract BigDecimal specificCalculate(int amount);
}
static class FruitService extends AbstractGoodsService {
@Override
public BigDecimal specificCalculate(int amount) {
System.out.println("执行水果类商品的优惠政策");
return new BigDecimal("0.99").multiply(new BigDecimal(String.valueOf(amount)));
}
}
static class HomeAppliancesService extends AbstractGoodsService {
@Override
public BigDecimal specificCalculate(int amount) {
System.out.println("执行家电类商品的优惠政策");
return new BigDecimal("0.8").multiply(new BigDecimal(String.valueOf(amount)));
}
}
AbstractGoodsService类中定义执行流程,当需要修改流程时直接改这个类即可;对应商品折扣类型、优惠政策等非常的适用