每天一个设计模式之Template Method

http://www.oodesign.com/template-method-pattern.html

 

A template method defines an algorithm in a base class using abstract operations that subclasses override to provide concrete behavior.

例如做披萨的过程:和面,加馅料,烘烤。这一整个过程就可以做成一个template,也就是模板。但是对于不同种类的披萨,加馅料这步肯定是不同的,需要不用的子类来实现。

template method属于behavioral pattern。

看上去就是很基本的对抽象类的使用,对吧?注意在这个模式中,并不一定要使用抽象类,用一个concrete父类也可以。这一点后面会有更多的的解释。

 

目的

- Define the skeleton of an algorithm in an operation, deferring some steps to subclasses.
- Template Method lets subclasses redefine certain steps of an algorithm without letting them to change the algorithm's structure.

 

下面是一个简单的例子:在一个旅行社中有packageA和packageB两种旅游路线。

 

父类performTrip方法定义了所谓的骨架:一个旅游路线必须包含的内容。这个框架是固定的,且不应被子类覆盖。因此使用了final关键字。

而框架中包含的每个steps,必须在子类中被具体定义,因此父类使用了抽象方法。也就是说在这个例子中父类仅定义了框架,而没有涉及任何实际的功能。而在实际使用中,仍然可以在父类中实现一部分具体功能。

 

public class Trip {
        public final void performTrip(){
                 doComingTransport(); //这叫primitive method.
                 doDayA();
                 doDayB();
                 doDayC();
                 doReturningTransport();
        }
        public abstract void doComingTransport();
        public abstract void doDayA();
        public abstract void doDayB();
        public abstract void doDayC();
        public abstract void doReturningTransport();
}
//为了让代码更清晰可以在命名上使用perform,do,pre or post等字眼。

public class PackageA extends Trip {
        public void doComingTransport() {
                 System.out.println("The turists are comming by air ...");
        }
        public void doDayA() {
                 System.out.println("The turists are visiting the aquarium ...");
        }
        public void doDayB() {
                 System.out.println("The turists are going to the beach ...");
        }
        public void doDayC() {
                 System.out.println("The turists are going to mountains ...");
        }
        public void doReturningTransport() {
                 System.out.println("The turists are going home by air ...");
        }
}
public class PackageB extends Trip {
        public void doComingTransport() {
                 System.out.println("The turists are comming by train ...");
        }
        public void doDayA() {
                 System.out.println("The turists are visiting the mountain ...");
        }
        public void doDayB() {
                 System.out.println("The turists are going to the beach ...");
        }
        public void doDayC() {
                 System.out.println("The turists are going to zoo ...");
        }
        public void doReturningTransport() {
                 System.out.println("The turists are going home by train ...");
        }
}

看完了这个例子我们可能会想:如果不使用这种结构,仅在父类中定义所有方法:

        public abstract void doComingTransport();
        public abstract void doDayA();
        public abstract void doDayB();
        public abstract void doDayC();
        public abstract void doReturningTransport();

然后在子类中实现也完全没有问题。但是在外部调用时,使用template method就可以调用performTrip()即可。而仅使用最简单的父子继承关系,则需要调用所有方法:

ConcreteClass.doComingTransport();

ConcreteClass.doDayA();
ConcreteClass.doDayB();

ConcreteClass.doDayC();
ConcreteClass.doReturningTransport();

这时不够清晰,而且容易出错。这就是为什么template method实现的不仅仅是“接口”,而是“框架”。


下面谈谈上面提到的,一定要使用抽象类吗?

我们知道如果使用抽象方法,则类就是抽象的。而抽象方法在子类中必须被实现,因为抽象方法完全没有方法体。如果不实现则无法通过编译:

public abstract void doDayA();

 

而如果我们在template method模式中使用concrete class,则没有这种好处。因为override父类的方法是optional的。

所以通常情况使用template pattern,一定会使用抽象类。但下面我们将谈到一种特殊情况。

 class Subclass extends Superclass
{
    ...
    void something() {
    // some customization code to extend functionality
    super. something ();
    // some customization code to extend functionality
    }
}


在这段代码中调用了父类的方法。文章中称之为hooks。为了解决两个问题

1,有时候会忘记调用父类方法。

2,读代码时不得不去看父类的代码。

所以使用了template method。此时的父类不必是抽象类。

(老实说这理由太牵强了。。。感兴趣的同学自己去看原文吧。。。)

 

另外一点:

When there is a method in the base class that should contain default some code, but on the other side it's necessary to be extended in the subclasses it should be split in 2 methods。

最后一句比较经典的话:

Template Method and Strategy Design Pattern

The strategy pattern is with Template Method pattern. The difference consists in the fact that Strategy uses delegation while the Template Methods uses the inheritance.

这两个pattern的共同之处就是,都是将代码中的算法/variant 的部分独立出来。

pattern太多了,多思考一下每个pattern的异同不仅利于理解,还不容易混乱。。。哈哈

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值