模板方法模式( Template Method Pattern ): 工厂方法模式的情侣

  1. 参考书籍: 《Design Patterns: Elements of Reusable Object-Oriented Software》

模板方法模式和工厂方法模式分别隶属于行为模式(Behavioral Pattern)和创建类模式(创建型模式), 但是他们的核心思想却十分相似, 而且通常会同时出现。

模板方法模式

  • 设计动机
    • 将一个操作整体步骤定义好,把其中的一部分具体步骤延迟到子类去实现。模板方法可以让子类在不改变算法整体结构的情况下, 重新定义其中的特定步骤。
    • 举例: 假设现在要编写一个支持屠宰家畜的框架, 家畜的类型包括牛羊等, 于是希望先定义一个屠宰场类 KillHouse, 该屠宰场会在调用KillAnimal(Animal animal) 方法时会接受运行时传入的参数(Sheep、Chicken ) 。现在假设, 宰杀家畜这个行为的整体操作流程是基本固定的,比如都是首先要判断传入的对象是不是可宰杀的牲畜, 如果可宰杀, 则先做一些准备工作customPrepareWork(),需要的准备工作可能会因为牲畜类型不同而不同, 然后调用一把刀(Knife)的chop( animal)方法, 宰杀完毕以后, 事后再进行一些通用的清理现场的工作 。
      • 在以上的描述中 , 假设了宰杀牲畜前的准备工作因动物而异, 宰杀后的清理工作对于不同类型的牲畜都是通用的, 所以这一部分是可以被复用的代码, 可以放到父类中实现。 然后由子类去重写准备工作的方法customPrepareWork()。
abstract public class KillHouse {

    private Knife knife = new DefaultKnife();

    public void killAnimal(Animal animal)
    {
        if(animal.canBeKilled)
        {
            // 有一些因动物类别而不同的准备步骤需要
            customPrepareWork();
            knife.chop(animal); // 宰杀动物的操作
            // 有一些通用的清理步骤
            commonCleanWork();
        }
        else{
            // 报警: 遭遇了不可宰杀的动物
        }

    }

    protected abstract void customPrepareWork();

    private void commonCleanWork() {
        //通用的清理步骤
    }

}
public class KillCowHouse extends KillHouse {
    @Override
    protected void customPrepareWork() {
        // 重写父类的方法, 实现杀牛之前独特的准备工作
    }

}

通过以上的代码可以发现, 父类固定了宰杀家禽killAnimal这项操作的整体结构或整体步骤, 实现了通用的清理工作, 子类KillCowHouse 重写了需要根据动物类型定制的准备工作。 killAnimal( Animal animal) 这个方法就是一个模板方法

模板方法模式与工厂方法模式之间的情侣关系

注意到之前编写的代码样例中, 用到了Knife来宰杀动物, 这个对象的获得是通过在父类里直接new DefaultKnife 完成的, 这样的话, 其实所有的动物,不论是牛还是鸡都在用同一把刀宰杀, 现假设杀鸡不能用牛刀的, 且想把刀的实例化工作,放到通用的准备工作中去, 则就会应用到工厂方法模式, 变成如下的样子。

abstract public class KillHouse {

    private Knife knife = null; 

    public void killAnimal(Animal animal)
    {
        if(animal.canBeKilled)
        {
            // 有一些因动物类别而不同的准备步骤需要
            customPrepareWork();

            knife = createKnife();

            if(knife != null)
            {
                knife.chop(animal); // 宰杀动物的操作
                // 有一些通用的清理步骤
                commonCleanWork();
            }else{
                // 报警: 没有成功获取到刀。 
            }

        }
        else{
            // 报警: 遭遇了不可宰杀的动物
        }

    }

    protected abstract void customPrepareWork();
    protected abstract Knife createKnife();  // 新增的工厂方法

    private void commonCleanWork() {
        //通用的清理步骤
    }

}
public class KillCowHouse extends KillHouse {
    @Override
    protected Knife createKnife() {
        return new CowKnife();
    }

    @Override
    protected void customPrepareWork() {
        // 重写父类的方法, 实现杀牛之前独特的准备工作
    }


}

通过以上的例子可以发现, 由于子类可能需要使用的实例不同, 所以增加了一个工厂方法, 把刀的实例化操作留给了子类去重写。 在这个过程中, 模板方法 killAnimal(Animal animal) 中调用了 createKnife() 这个工厂方法。

  • 总结:
    • 模板方式和工厂模式的核心思想非常类似, 都是把一些操作留给子类去实现。
    • 模板方法中常常会调用工厂方法的, 他们之间存在着的紧密的情侣关系。
    • 工厂方法模式和模板方法模式的区别在于:
      • 模板方法模式的意义在于固定了一个算法的整体结构, 复用了其中通用的步骤, 将需要定制的部分留给了子类实现
      • 工厂方法模式的意义在于解决了父类没有办法预知应该实现什么子类的问题
  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
模板方法模式Template Method Pattern)是一种行为型设计模式,它定义了一个操作中的算法框架,将一些步骤延迟到子类中实现。模板方法模式使得子类可以在不改变算法结构的情况下重新定义算法的某些步骤。 在模板方法模式中,定义一个抽象类作为算法的框架,其中包含了一个或多个抽象方法,这些抽象方法由子类来实现。除了抽象方法之外,抽象类还可以包含具体方法,这些具体方法在算法中的步骤中起到固定的作用。 使用模板方法模式可以将算法的实现细节封装在抽象类中,子类只需要关注具体的实现细节。这样做的好处是可以提高代码的复用性,减少冗余代码的编写。同时,模板方法模式还可以提供一个可扩展的框架,允许在不改变算法结构的情况下修改算法的某些步骤。 抽象类是一种不能被实例化的类,它主要用于定义一个接口,并提供一些默认的实现。在模板方法模式中,抽象类扮演着定义算法框架和部分具体实现的角色。抽象类中的抽象方法需要由子类来实现,而具体方法可以在抽象类中直接提供默认实现。 总结来说,模板方法模式通过定义一个算法框架和抽象类,将算法的具体实现细节延迟到子类中去实现。抽象类中的抽象方法由子类来实现,具体方法可以在抽象类中提供默认实现。这种设计模式提供了一种灵活的方式来定义算法的结构,同时也提高了代码的复用性和扩展性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值