📜  模板方法设计模式

📅  最后修改于: 2021-09-10 02:45:37             🧑  作者: Mango

模板方法设计模式是将算法定义为操作的骨架,细节由子类实现。算法的整体结构和序列由父类保留。
模板是指具有固定预设格式的 HTML 模板等预设格式。同样在模板方法模式中,我们有一个预设的结构方法叫做模板方法,它由步骤组成。这些步骤可以是一个抽象方法,将由其子类实现。

这种行为设计模式是最容易理解和实现的模式之一。这种设计模式在框架开发中广泛使用。这也有助于避免代码重复。


来源:维基百科

  • AbstractClass包含 templateMethod() ,它应该是最终的,以便它不能被覆盖。该模板方法利用其他可用操作来运行算法,但在这些方法的实际实现中是分离的。此模板方法使用的所有操作都是抽象的,因此它们的实现被推迟到子类。
  • ConcreteClass实现了 templateMethod 所需的所有操作,这些操作在父类中定义为抽象。可以有许多不同的具体类。

让我们看一个模板方法模式的例子。

abstract class OrderProcessTemplate
{
    public boolean isGift;
  
    public abstract void doSelect();
  
    public abstract void doPayment();
  
    public final void giftWrap()
    {
        try
        {
            System.out.println("Gift wrap successful");
        }
        catch (Exception e)
        {
            System.out.println("Gift wrap unsuccessful");
        }
    }
  
    public abstract void doDelivery();
  
    public final void processOrder(boolean isGift)
    {
        doSelect();
        doPayment();
        if (isGift) {
            giftWrap();
        }
        doDelivery();
    }
}
  
  
class NetOrder extends OrderProcessTemplate
{
    @Override
    public void doSelect()
    {
        System.out.println("Item added to online shopping cart");
        System.out.println("Get gift wrap preference");
        System.out.println("Get delivery address.");
    }
  
    @Override
    public void doPayment()
    {
        System.out.println
                   ("Online Payment through Netbanking, card or Paytm");
    }
  
    @Override
    public void doDelivery()
    {
        System.out.println
                    ("Ship the item through post to delivery address");
    }
  
}
  
class StoreOrder extends OrderProcessTemplate
{
  
    @Override
    public void doSelect()
    {
        System.out.println("Customer chooses the item from shelf.");
    }
  
    @Override
    public void doPayment()
    {
        System.out.println("Pays at counter through cash/POS");
    }
  
    @Override
    public void doDelivery()
    {
        System.out.println("Item delivered to in delivery counter.");
    }
  
}
  
class TemplateMethodPatternClient
{
    public static void main(String[] args)
    {
        OrderProcessTemplate netOrder = new NetOrder();
        netOrder.processOrder(true);
        System.out.println();
        OrderProcessTemplate storeOrder = new StoreOrder();
        storeOrder.processOrder(true);
    }
}

输出 :

Item added to online shopping cart
Get gift wrap preference
Get delivery address.
Online Payment through Netbanking, card or Paytm
Gift wrap successful
Ship the item through post to delivery address

Customer chooses the item from shelf.
Pays at counter through cash/POS
Gift wrap successful
Item delivered to in delivery counter.

上面的例子处理订单处理流程。 OrderProcessTemplate 类是一个包含算法骨架的抽象类。如注释所示,processOrder() 是包含流程步骤的方法。我们有两个子类 NetOrder 和 StoreOrder,它们具有相同的订单处理步骤。

因此用于处理订单的整体算法在基类中定义并由子类使用。但是执行单个操作的方式因子类而异。

何时使用模板方法

模板方法用于框架中,其中每个框架都实现域架构的不变部分,为自定义选项留下“占位符”。

使用模板方法的原因如下:

  • 让子类实现不同的行为(通过方法覆盖)
  • 避免代码重复,一般工作流结构在抽象类的算法中实现一次,必要的变化在子类中实现。
  • 控制允许子类化的点。与简单的多态覆盖相反,基本方法将被完全重写,允许对工作流进行彻底的更改,只允许更改工作流的特定细节。

参考 :
维基百科