一 什么是模板模式
模板模式是在一个抽象类中定义了执行它的方法的方式(模板方法),由抽象类的子类根据具体的业务需求去重写父类的中方法,但执行时将调用抽象类中定义的方式进行。
二 模板模式原理分析
在模板模式中,我们需要2个类,如下图
1 抽象的父类:在父类中,我们定义模板方法;
2具体的实现的子类:在子类中,重写父类中定义的模板方法,不同的子类,可以按照各自不同的业务逻辑去实现,以供调用
三 模板模式举例实现
举个例子,用代码简单的实现模板模式
在我们的项目中有一个支付的业务场景(医院信息化系统)。患者在做检查前需要先去缴费(支付),缴费后会收到打印的缴费单,拿到缴费单之后再去做检查。目前系统中支持的缴费方式有3种(支付宝、微信、现金)
首先,我们将支付相关方法提取出来,定义抽象类模板方法,pay方法是我们的骨架方法,具体由其他方法完成,
1 public abstract class AbstractPayment { 2 3 public void pay() { 4 //支付前 5 beforePay(); 6 //实现支付 7 doPay(); 8 //支付后 9 afterPay(); 10 } 11 12 public void beforePay(){ 13 } 14 15 public void doPay(){ 16 } 17 18 public void afterPay(){ 19 } 20 }
其次,根据支付方式,完成对应的实现(支付类继承并重写父类方法)
1 支付宝支付类
1 public class AliPay extends AbstractPayment { 2 3 @Override 4 public void beforePay() { 5 System.out.println("支付宝支付------支付前数据组装"); 6 } 7 8 @Override 9 public void doPay() { 10 System.out.println("调用支付宝支付API------完成支付"); 11 } 12 13 @Override 14 public void afterPay() { 15 System.out.println("支付宝支付------支付后打印缴费单"); 16 } 17 }
2 微信支付类
1 public class WxPay extends AbstractPayment { 2 3 @Override 4 public void beforePay() { 5 System.out.println("微信支付------支付前数据组装"); 6 } 7 8 @Override 9 public void doPay() { 10 System.out.println("调用微信支付API------完成支付"); 11 } 12 13 @Override 14 public void afterPay() { 15 System.out.println("微信支付------支付后打印缴费单"); 16 } 17 }
3 现金支付类
1 public class CashPay extends AbstractPayment { 2 3 @Override 4 public void beforePay() { 5 System.out.println("现金支付------支付前金额确认"); 6 } 7 8 @Override 9 public void doPay() { 10 System.out.println("现金支付------完成支付"); 11 } 12 13 @Override 14 public void afterPay() { 15 System.out.println("现金支付------支付后打印缴费单"); 16 } 17 }
四 测试
上边简单的模拟实现了模板模式,抽象类的子类根据各自业务逻辑分别重写了beforePay,doPay,afterPay方法。我们写个main方法做个测试
1 public static void main(String[] args) { 2 3 AliPay aliPay = new AliPay(); 4 aliPay.pay(); 5 6 WxPay wxPay = new WxPay(); 7 wxPay.pay(); 8 9 CashPay cashPay = new CashPay(); 10 cashPay.pay(); 11 12 }
控制台输出结果如下
上边这个例子中,我们把不变的方法pay交给抽象父类管理,可变的方法beforePay,doPay,afterPay交给子类做扩展实现,代码看起来很统一,出现问题时也很容易定位问题。但也存在一个类似静态代理的缺点,就是如果我们有很多种支付方式时,我们就需要写很多个支付子类去继承抽象类,进而导致很多的对象类文件,系统也会变得很庞大。