注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

写着玩

Bob

 
 
 

日志

 
 
 
 

设计模式的解析和实现(C++)之十一-TemplateMethod模式  

2009-06-16 22:50:59|  分类: GOF设计模式 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

http://www.lifevv.com/sysdesign/doc/20071106175357564.html

 

作用:

  定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。TemplateMethod 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

  UML结构图:

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客

  抽象基类:

  1)AbstractClass:抽象基类,定义算法的轮廓

  解析:

  TemplateMethod 的关键在于在基类中定义了一个算法的轮廓,但是算法每一步具体的实现留给了派生类.但是这样也会造成设计的灵活性不高的缺点,因为轮廓已经定下来了要想改变就比较难了,这也是为什么优先采用聚合而不是继承的原因.

  实现:

  1)TemplateMethod.h

/**//********************************************************************

    created:    2006/07/20

    filename:     TemplateMethod.h

    author:        李创

                http://www.cppblog.com/converse/

    purpose:    TemplateMethod模式的演示代码

*********************************************************************/

// 抽象基类,定义算法的轮廓

class AbstractClass

{

public:

    AbstractClass(){}

    virtual ~AbstractClass(){}

    // 这个函数中定义了算法的轮廓

    void TemplateMethod();

protected:

    // 纯虚函数,由派生类实现之

    virtual void PrimitiveOperation1() = 0;

    virtual void PrimitiveOperation2() = 0;

};

// 继承自AbstractClass,实现算法

class ConcreateClass

    : public AbstractClass

{

public:

    ConcreateClass(){}

    virtual ~ConcreateClass(){}

protected:

    virtual void PrimitiveOperation1();

    virtual void PrimitiveOperation2();

};

2)TemplateMethod.cpp

/**//********************************************************************

    created:    2006/07/20

    filename:     TemplateMethod.cpp

    author:        李创

                http://www.cppblog.com/converse/

    purpose:    TemplateMethod模式的演示代码

*********************************************************************/

#include "TemplateMethod.h"

#include <iostream>

void AbstractClass::TemplateMethod()

{

    PrimitiveOperation1();

    PrimitiveOperation2();

}

void ConcreateClass::PrimitiveOperation1()

{

    std::cout << "PrimitiveOperation1 by ConcreateClassn";

}

void ConcreateClass::PrimitiveOperation2()

{

    std::cout << "PrimitiveOperation2 by ConcreateClassn";

}

  3)Main.cpp

/**//********************************************************************

    created:    2006/07/20

    filename:     Main.cpp

    author:        李创

                http://www.cppblog.com/converse/

    purpose:    TemplateMethod模式的测试代码

*********************************************************************/

#include "TemplateMethod.h"

#include <stdlib.h>

int main()

{

    AbstractClass* pConcreateClass = new ConcreateClass;

    pConcreateClass->TemplateMethod();

    delete pConcreateClass;

    system("pause");

    return 0;

}

以下转载自:http://www.cnblogs.com/zhenyulu/articles/79894.html

一、 模板方法(Template Method)模式

准备一个抽象类,将部分逻辑以具体方法以及具体构造子的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。这就是模版方法模式的用意。

很多人可能没有想到,模版方法模式实际上是所有模式中最为常见的几个模式之一,而且很多人可能使用过模版方法模式而没有意识到自己已经使用了这个模式。模版方法模式是基于继承的代码复用的基本技术,模版方法模式的结构和用法也是面向对象设计的核心。

模版方法模式需要开发抽象类和具体子类的设计师之间的协作。一个设计师负责给出一个算法的轮廓和骨架,另一些设计师则负责给出这个算法的各个逻辑步骤。代表这些具体逻辑步骤的方法称做基本方法(primitive method);而将这些基本法方法总汇起来的方法叫做模版方法(template method),这个设计模式的名字就是从此而来。

二、 模版方法模式的结构

模版方法模式的静态结构如下图所示。

 设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客

这里涉及到两个角色:

  • 抽象模版(AbstractClass)角色有如下的责任:

定义了一个或多个抽象操作,以便让子类实现。这些抽象操作叫做基本操作,它们是一个顶级逻辑的组成步骤。

定义并实现了一个模版方法。这个模版方法一般是一个具体方法,它给出了一个顶级逻辑的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类实现。顶级逻辑也有可能调用一些具体方法。

  • 具体模版(ConcreteClass)角色有如下的责任:

实现父类所定义的一个或多个抽象方法,它们是一个顶级逻辑的组成步骤。

每一个抽象模版角色都可以有任意多个具体模版角色与之对应,而每一个具体模版角色都可以给出这些抽象方法(也就是顶级逻辑的组成步骤)的不同实现,从而使得顶级逻辑的实现各不相同。

三、 模板方法模式的示意性代码

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客// Template Method pattern -- Structural example  

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客using System;

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客// "AbstractClass"

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客abstract class AbstractClass

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客{

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  // Methods

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  abstract public void PrimitiveOperation1();

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  abstract public void PrimitiveOperation2();

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  // The Template method

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  public void TemplateMethod()

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客{

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客    Console.WriteLine("In AbstractClass.TemplateMethod()");

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客    PrimitiveOperation1();

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客    PrimitiveOperation2();

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  }

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客}

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客// "ConcreteClass"

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客class ConcreteClass : AbstractClass

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客{

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  // Methods

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  public override void PrimitiveOperation1()

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客{

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客    Console.WriteLine("Called ConcreteClass.PrimitiveOperation1()");

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  }

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  public override void PrimitiveOperation2()

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客{

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客    Console.WriteLine("Called ConcreteClass.PrimitiveOperation2()");

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  }

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客}

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客/**//// <summary>

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客/// Client test

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客/// </summary>

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客public class Client

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客{

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  public static void Main( string[] args )

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客{

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客    // Create instance and call template method

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客    ConcreteClass c = new ConcreteClass();

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客    c.TemplateMethod();

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  }

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客}

四、 继承作为复用的工具

使用继承作为复用的手段必须慎重,C#语言的设计师对使用继承作为复用的工具有着不同层次上的认识。

不知其一

首先,初学C#的程序员可能不知道什么是继承,或者认为"继承"是高深的工具。那时候,大部分的功能复用都是通过委派进行的。

知其一、不知其二

然后慢慢地,他们发现在C#语言里实现继承并不困难,并且初步认识到继承可以使子类一下子得到基类的行为。这时他们就会跃跃欲试了,试图使用继承作为功能复用的主要工具,并把原来应当使用委派的地方,改为使用继承,这时继承就有被滥用的危险。

知其二

很多面向对象的设计专家从1986年就开始警告继承关系被滥用的可能。有一些面向对象的编程语言,如SELF语言,甚至将类的继承关系从语言的功能中取消掉,改为完全使用委派。

其他的设计师虽然不提倡彻底取消继承,但无一例外地鼓励在设计中尽可能使甩委派关系代替继承关系。比如在【GOF95】一书中,状态模式、策略模式、装饰模式、桥梁模式以及抽象工厂模式均是将依赖于继承的实现转换为基于对象的组合和聚合的实现,这些模式的要点就是使用委派关系代替继承关系。

知其三

是不是继承就根本不该使用呢?事实上对数据的抽象化、继承、封装和多态性并称C#和其他绝大多数的面向对象语言的几项最重要的特性。继承不应当被滥用,并不意味着继承根本就不该使用。因为继承容易被滥用就彻底抛弃继承,无异于因噎废食。

继承使得类型的等级结构易于理解、维护和扩展,而类型的等级结构非常适合于抽象化的设计、实现和复用。尽管【GOF95】所给出的设计模式基本上没有太多基于继承的模式,很多模式都是用继承的办法定义、实现接口的。多数的设计模式都描写一个以抽象类作为基类,以具体类作为实现的等级结构,比如适配器模式、合成模式、桥梁模式、状态模式等。

模版方法模式则更进了一步:此模式鼓励恰当地使用继承。此模式可以用来改写一些拥有相同功能的相关的类,将可复用的一般性的行为代码移到基类里面,而把特殊化的行为代码移到子类里面。

因此,熟悉模版方法模式便成为一个重新学习继承的好地方。

五、 一个实际应用模板方法的例子

下面的例子演示了数据库访问的模板方法。实际应用时,请确保C盘根目录下有nwind.mdb这个Access数据库(可以从Office的安装目录下找到。中文版用户的请注意字段名可能有所不同)。

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客// Template Method pattern -- Real World example  

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客using System;

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客using System.Data;

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客using System.Data.OleDb;

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客// "AbstractClass"

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客abstract class DataObject

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客{

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  // Methods

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  abstract public void Connect();

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  abstract public void Select();

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  abstract public void Process();

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  abstract public void Disconnect();

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  // The "Template Method"

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  public void Run()

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客{

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客    Connect();

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客    Select();

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客    Process();

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客    Disconnect();

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  }

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客}

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客// "ConcreteClass"

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客class CustomerDataObject : DataObject

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客{

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  private string connectionString =

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客    "provider=Microsoft.JET.OLEDB.4.0; "

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客    + "data source=c:\\nwind.mdb";

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  private string commandString;

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  private DataSet dataSet;

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客 

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  // Methods

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  public override void Connect( )

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客{

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客    // Nothing to do

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  }

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  public override void Select( )

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客{

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客    commandString = "select CompanyName from Customers";

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客    OleDbDataAdapter dataAdapter = new OleDbDataAdapter(

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客      commandString, connectionString );

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客    dataSet = new DataSet();

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客    dataAdapter.Fill( dataSet, "Customers" );

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  }

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  public override void Process()

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客{

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客    DataTable dataTable = dataSet.Tables["Customers"];

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客    foreach( DataRow dataRow in dataTable.Rows )

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客      Console.WriteLine( dataRow[ "CompanyName" ] );

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  }

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  public override void Disconnect()

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客{

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客    // Nothing to do

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  }

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客}

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客/**//// <summary>

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客///  TemplateMethodApp test

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客/// </summary>

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客public class TemplateMethodApp

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客{

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  public static void Main( string[] args )

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客{

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客    CustomerDataObject c = new CustomerDataObject( );

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客    c.Run();

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客  }

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客}

 

六、 模版方法模式中的方法

模版方法中的方法可以分为两大类:模版方法(Template Method)和基本方法(Primitive Method)。

模版方法

一个模版方法是定义在抽象类中的,把基本操作方法组合在一起形成一个总算法或一个总行为的方法。这个模版方法一般会在抽象类中定义,并由子类不加以修改地完全继承下来。

基本方法

基本方法又可以分为三种:抽象方法(Abstract Method)、具体方法(Concrete Method)和钩子方法(Hook Method)。

抽象方法:一个抽象方法由抽象类声明,由具体子类实现。在C#语言里一个抽象方法以abstract关键字标示出来。

具体方法:一个具体方法由抽象类声明并实现,而子类并不实现或置换。在C#语言里面,一个具体方法没有abstract关键字。

钩子方法:一个钩子方法由抽象类声明并实现,而子类会加以扩展。通常抽象类给出的实现是一个空实现,作为方法的默认实现。(Visual FoxPro中项目向导建立的项目会使用一个AppHook类实现监视项目成员变化,调整系统结构的工作。)钩子方法的名字通常以do开始。

七、 重构的原则

在对一个继承的等级结构做重构时,一个应当遵从的原则便是将行为尽量移动到结构的高端,而将状态尽量移动到结构的低端。

1995年,Auer曾在文献【AUER95】中指出:

  1. 应当根据行为而不是状态定义一个类。也就是说,一个类的实现首先建立在行为的基础之上,而不是建立在状态的基础之上。
  2. 在实现行为时,是用抽象状态而不是用具体状态。如果一个行为涉及到对象的状态时,使用间接的引用而不是直接的引用。换言之,应当使用取值方法而不是直接引用属性。
  3. 给操作划分层次。一个类的行为应当放到一个小组核心方法(Kernel Methods)里面,这些方法可以很方便地在子类中加以置换。
  4.  将状态属性的确认推迟到子类中。不要在抽象类中过早地声明属性变量,应将它们尽量地推迟到子类中去声明。在抽象超类中,如果需要状态属性的话,可以调用抽象的取值方法,而将抽象的取值方法的实现放到具体子类中。

如果能够遵从这样的原则,那么就可以在等级结构中将接口与实现分隔开来,将抽象与具体分割开来,从而保证代码可以最大限度地被复用。这个过程实际上是将设计师引导到模版方法模式上去。

 

 

以下转载自:

http://www.lifevv.com/sysdesign/doc/20071106175357564.html

设计模式之Template Method - 模板方法模式

 

Template Method模式也叫模板方法模式,是由GoF提出的23种设计模式中的一种。Template Method模式是行为模式之一,它把具有特定步骤算法中的某些必要的处理委让给抽象方法,通过子类继承对抽象方法的不同实现改变整个算法的行为。

本文介绍设计模式中的模板方法(Template Method)模式的概念,用法,以及实际应用中怎么样使用Template Method模式进行开发。

Template Method模式的概念

Template Method模式正如其名,在作为抽象类的父类里,定义了一个具有固定算法并可以细分为多个步骤的模板方法(public),Template Method模式把这些可以被细分的可变步骤抽象为可以被子类重载的抽象方法(protected abstract),并通过在子类中的重载(重新定义),做到无需改变模板方法的算法步骤而可以重新定义该算法中的某些特定的步骤。

如图[该图出自维基百科wikipedia.org]:

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客

我们结合上面的定义解释一下该图。

- AbstractClass便相当于上述作为抽象类的父类,ConcreteClass便是具体的实现子类。具体的应用中,可能存在一到多个实现子类。

- AbstractClass定义了一个public的templateMethod()模板方法以及作为步骤的method1()与method2()方法。

- AbstractClass#templateMethod()方法体调用method1()与method2()方法

    public void templateMethod() {

        ...

        this.method()1;

        ...

        this.method()2;

        ...

    }

- method1()与method2()方法为受保护的抽象方法(protected abstract)。实现子类ConcreteClass需要重载该方法。

Template Method模式的应用场景

Template Method模式一般应用在具有以下条件的应用中:

- 具有统一的操作步骤或操作过程

- 具有不同的操作细节

- 存在多个具有同样操作步骤的应用场景,但某些具体的操作细节却各不相同

Template Method模式的应用范例

下面我们举个例子来加深我们对Template Method模式的理解。

比如有一个汽车加工厂,要组装一辆汽车;它的基本组装步骤是:

- 组装车头

- 组装车身

- 组装车尾

- 测试组装的车体

不管被组装的是吉普车,卡车,还是公交车,它们的基本组装步骤都是一样的,虽然在组装的步骤中,会有细微的差别。

通过上面的分析,我们知道,该范例满足Template Method模式的应用场景所提到的条件:

- 具有统一的操作步骤或操作过程:组装的步骤一样

- 具有不同的操作细节:各步骤有细微的区别。例如,组装吉普车的车头需要吉普车的车头零件

- 存在多个具有同样操作步骤的应用场景,但某些具体的操作细节却各不相同。可能需要组装不同的汽车,如吉普车,卡车,公交车等等

下面我们用Template Method设计模式来抽象以上组装过程。

- MakeCar:汽车组装类

- MakeJeep:吉普车组装类

源代码

view plaincopy to clipboardprint?

  1. //汽车组装抽象类   
  2. public abstract class MakeCar {   
  3.     //组装车头   
  4.     abstract void makeHead();   
  5.     //组装车身   
  6.     abstract void makeBody();   
  7.     //组装车尾   
  8.     abstract void makeTail();   
  9.     //测试   
  10.     abstract boolean checkMake();   
  11.   
  12.     public void make() {   
  13.         System.out.println("Start make car...");   
  14.         makeHead();   
  15.         makeBody();   
  16.         makeTail();   
  17.         if (checkMake()) {   
  18.             System.out.println("Make OK.");   
  19.         } else {   
  20.             System.out.println("Make Failure.");   
  21.         }   
  22.   }   
  23. }   
  24.   
  25. //吉普车组装类   
  26. public class MakeJeep extends MakeCar {   
  27.     //组装车头   
  28.     void makeHead() {   
  29.         System.out.println("Make Jeep head.");   
  30.     }   
  31.     //组装车身   
  32.     void makeBody() {   
  33.         System.out.println("Make Jeep body.");   
  34.     }   
  35.     //组装车尾   
  36.     void makeTail() {   
  37.         System.out.println("Make Jeep tail.");   
  38.     }   
  39.     //测试   
  40.     boolean checkMake() {   
  41.         return true;   
  42.     }   
  43. }   
  44.   
  45. //调用   
  46. public class Client {   
  47.     public static void main(String[] args) {   
  48.         MakeJeep makeJeep = new MakeJeep();   
  49.   
  50.         makeJeep.make();   
  51.     }   
  52. }  

//汽车组装抽象类public abstract class MakeCar {    //组装车头    abstract void makeHead();    //组装车身    abstract void makeBody();    //组装车尾    abstract void makeTail();    //测试    abstract boolean checkMake();    public void make() {        System.out.println("Start make car...");        makeHead();        makeBody();        makeTail();        if (checkMake()) {            System.out.println("Make OK.");        } else {            System.out.println("Make Failure.");        }  }}//吉普车组装类public class MakeJeep extends MakeCar {    //组装车头    void makeHead() {        System.out.println("Make Jeep head.");    }    //组装车身    void makeBody() {        System.out.println("Make Jeep body.");    }    //组装车尾    void makeTail() {        System.out.println("Make Jeep tail.");    }    //测试    boolean checkMake() {        return true;    }}//调用public class Client {    public static void main(String[] args) {        MakeJeep makeJeep = new MakeJeep();        makeJeep.make();    }}

运行并显示Client:

C:\TemplateMethod>javac *.java

C:\TemplateMethod>java Client

Start make car...

Make Jeep head.

Make Jeep body.

Make Jeep tail.

Make OK.

C:\TemplateMethod>

Template Method模式与Factory Method模式的区别

我们在

设计模式的解析和实现(C++)之十一-TemplateMethod模式 - yolcy - yolcy的博客设计模式之Factory Method - 工厂模式

一文中对Factory Method模式作了介绍,细心的读者可能会发现,这2种模式存在相似的地方:

都是在抽象父类中定义抽象方法,通过子类继承在子类中重载父类的抽象方法来实现。

但他们之间存在本质的区别:

Template Method只是继承的关系,Factory Method除了继承之外,还有有创建的过程。

我们注意到,在Factory Method模式中,被定义的抽象方法创建了产品对象,也就是说,在Factory Method模式中,除了具有继承关系的抽象父类工厂与具体的子类工厂之外,还有具有继承关系的产品类,并且工厂类与产品类之间存在创建与被创建的关系;而Template Method模式则不存在此关系。

Template Method模式小结

Template Method模式是一种非常基础非常常见的面向对象的设计模式之一,在实际的应用中,它用得非常广泛。

  评论这张
 
阅读(735)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017