Creative Commons License
本Blog采用 知识共享署名-非商业性使用-禁止演绎 3.0 Unported许可协议 进行许可。 —— Fox <游戏人生>

游戏人生

游戏人生 != ( 人生 == 游戏 )
站点迁移至:http://www.yulefox.com。请订阅本博的朋友将RSS修改为http://feeds.feedburner.com/yulefox
posts - 62, comments - 508, trackbacks - 0, articles - 7

设计模式(四)——Template Method

Posted on 2009-02-11 01:46 Fox 阅读(1947) 评论(2)  编辑 收藏 引用 所属分类: T技术碎语

在一个稍微上规模(怎么也有几十个类吧)的C++程序中,继承和组合的使用比比皆是。虽然GoF提出了OOD的两个原则,第二个谓之『优先使用对象组合,而不是继承』,但这绝不意味着不使用继承,正因如此,第一个原则才是『针对接口编程,而不是针对实现编程』,这两个原则清楚的表达了软件工程中『低耦合』的思想。

模板方法(Template Method)的意图正是『定义一个操作中的算法的框架,而将一些步骤延迟到子类中』。

注意,这里有个关键词『一些』,既然是『一些』,就意味着父类的的接口中已经实现了『一些』步骤,否则,父类便只提供了抽象接口。

这一情况是我们在编码时时常遇到的,父类实现了部分算法中的通用行为,子类根据自己的需求可对其进行必要扩充。

class CBase
{
public:
    // Default done
    virtual void Operation(void)
    {
        ...
    }
};

class CDerive :
    public CBase
{
public:
    virtual void Operation(void)
    {
        switch( ... )
        {
        case A: ...
        case B: ...
        case c: ...
        default:
            CBase::Operation();
        }
    }
};

因为对父类的不了解或是对子类的太了解,你以为CDerive::Operation()做了足够多,不需要CBase::Operation(),但实际上仍然需要的情况总在发生。

换一种方式,把Operation()作为模板方法,把DoOperation()作为可扩展的接口提供给子类实现:

class CBase
{
public:
    void SetFocus(void) { ... }
    void ResetFocus(void) { ... }
    // Call by user
    void Operation(void)
    {
        SetFocus();
        DoOperation();
        ResetFocus();
    }
    // Default done
    virtual void DoOperation(void) = 0;
};

class CDerive :
    public CBase
{
public:
    virtual void DoOperation(void)
    {
        ...
    }
};

模板方法只是提供了一个简单的封装技巧,当然不是所有的虚接口都这么写:)。


更多内容请移步我的个人主页

Feedback

# re: 设计模式(四)&mdash;&mdash;Template Method  回复  更多评论   

2009-08-17 19:31 by 李现民
使用template method意味着使用了继承, 现在我觉得这样的代码应该少用,但仍然还没有在实践上找到好的替代方案

# re: 设计模式(四)&mdash;&mdash;Template Method  回复  更多评论   

2012-08-17 22:17 by cheap chanel watches
chanel j12 watches

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理