`
linbzh
  • 浏览: 71348 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

template method模版方法模式

阅读更多

      template method模版方法模式,说白了,就是抽象类的运用。模版方法模式很多时候都在用,利用该模式可以实现提高代码的复用率。它把各子类相同的方法放在抽象类,避免了编写重复的代码,而其他可变的方法强制型地在各子类各自实现,实现代码规范性。
      在我们使用的一些软件包的时候,有一些要求我们继承其某个类,并实现其方法,例如struts的Action,要求实现execute方法。原因是在Action内部定义了一个实现其功能的代码架构,用户不必做其他的事情,只要在继承并实现execute方法即可。这样做的目的是使得代码有规范性,简化代码,并达到方便用户使用的目的。

分享到:
评论
1 楼 eric_619 2009-07-27  
一、引子

这是一个很简单的模式,却被非常广泛的使用。之所以简单是因为在这个模式中仅仅使用到了继承关系。

继承关系由于自身的缺陷,被专家们扣上了“罪恶”的帽子。“使用委派关系代替继承关系”,“尽量使用接口实现而不是抽象类继承”等等专家警告,让我们这些菜鸟对继承“另眼相看”。

其实,继承还是有很多自身的优点所在。只是被大家滥用的似乎缺点更加明显了。合理的利用继承关系,还是能对你的系统设计起到很好的作用的。而模板方法模式就是其中的一个使用范例。

二、定义与结构

GOF给模板方法(Template Method)模式定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。这里的算法的结构,可以理解为你根据需求设计出来的业务流程。特定的步骤就是指那些可能在内容上存在变数的环节。

可以看出来,模板方法模式也是为了巧妙解决变化对系统带来的影响而设计的。使用模板方法使系统扩展性增强,最小化了变化对系统的影响。这一点,在下面的举例中可以很明显的看出来。

来看下这个简单模式的结构吧:

1) AbstractClass(抽象类):定义了一到多个的抽象方法,以供具体的子类来实现它们;而且还要实现一个模板方法,来定义一个算法的骨架。该模板方法不仅调用前面的抽象方法,也可以调用其他的操作,只要能完成自身的使命。

2) ConcreteClass(具体类):实现父类中的抽象方法以完成算法中与特定子类相关的步骤。

下面是模板方法模式的结构图。直接把《设计模式》上的图拿过来用下:



三、举例

还是在我刚刚分析完源码的JUnit中找个例子吧。JUnit中的TestCase以及它的子类就是一个模板方法模式的例子。在TestCase这个抽象类中将整个测试的流程设置好了,比如先执行Setup方法初始化测试前提,在运行测试方法,然后再TearDown来取消测试设置。但是你将在Setup、TearDown里面作些什么呢?鬼才知道呢!!因此,而这些步骤的具体实现都延迟到子类中去,也就是你实现的测试类中。

来看下相关的源代码吧。

这是TestCase中,执行测试的模板方法。你可以看到,里面正像前面定义中所说的那样,它制定了“算法”的框架——先执行setUp方法来做下初始化,然后执行测试方法,最后执行tearDown释放你得到的资源。

public void runBare() throws Throwable {
setUp();

try {
runTest();
}

finally {
tearDown();
}
}

这就是上面使用的两个方法。与定义中不同的是,这两个方法并没有被实现为抽象方法,而是两个空的无为方法(被称为钩子方法)。这是因为在测试中,我们并不是必须要让测试程序使用这两个方法来初始化和释放资源的。如果是抽象方法,则子类们必须给它一个实现,不管用到用不到。这显然是不合理的。使用钩子方法,则你在需要的时候,可以在子类中重写这些方法。

protected void setUp() throws Exception {}
protected void tearDown() throws Exception {}

四、适用情况

根据上面对定义的分析,以及例子的说明,可以看出模板方法适用于以下情况:

1) 一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。

2) 各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。其实这可以说是一种好的编码习惯了。

3) 控制子类扩展。模板方法只在特定点调用操作,这样就只允许在这些点进行扩展。比如上面runBare()方法就只在runTest前面适用setUp方法。如果你不愿子类来修改你的模板方法定义的框架,你可以采用两种方式来做:一是在API中不体现出你的模板方法;二、将你的模板方法置为final就可以了。

可以看出,使用模板方法模式可以将代码的公共行为提取出来,达到复用的目的。而且,在模板方法模式中,是由父类的模板方法来控制子类中的具体实现。这样你在实现子类的时候,根本不需要对业务流程有太多的了解。

----------------------------------------------------------------
实例:
Template.java

Java代码
public abstract class Template   
{   
    public void fitment(){   
        decorate();   
        floor();   
        paint();   
    }   
  
    public abstract void floor();   
  
    public abstract void paint();   
  
    public abstract void decorate();   
};  
Java代码
public abstract class Template  
{  
    public void fitment(){  
        decorate();  
        floor();  
        paint();  
    }  
 
    public abstract void floor();  
 
    public abstract void paint();  
 
    public abstract void decorate();  
}; 

public abstract class Template
{
public void fitment(){
decorate();
floor();
paint();
}

public abstract void floor();

public abstract void paint();

public abstract void decorate();
};

Team1.java

Java代码
public class Team1 extends Template   
{   
    public void floor(){   
        System.out.println("Team1-----floor");   
    }   
  
    public void decorate(){   
        System.out.println("Team1-----decorate");   
    }   
  
    public void paint(){   
        System.out.println("Team1-----paint");   
    }   
};  
Java代码
public class Team1 extends Template  
{  
    public void floor(){  
        System.out.println("Team1-----floor");  
    }  
 
    public void decorate(){  
        System.out.println("Team1-----decorate");  
    }  
 
    public void paint(){  
        System.out.println("Team1-----paint");  
    }  
}; 

public class Team1 extends Template
{
public void floor(){
System.out.println("Team1-----floor");
}

public void decorate(){
System.out.println("Team1-----decorate");
}

public void paint(){
System.out.println("Team1-----paint");
}
};

Team2.java

Java代码
public class Team2 extends Template   
{   
    public void floor(){   
        System.out.println("Team2-----floor");   
    }   
  
    public void decorate(){   
        System.out.println("Team2-----decorate");   
    }   
  
    public void paint(){   
        System.out.println("Team2-----paint");   
    }   
};  
Java代码
public class Team2 extends Template  
{  
    public void floor(){  
        System.out.println("Team2-----floor");  
    }  
 
    public void decorate(){  
        System.out.println("Team2-----decorate");  
    }  
 
    public void paint(){  
        System.out.println("Team2-----paint");  
    }  
}; 

public class Team2 extends Template
{
public void floor(){
System.out.println("Team2-----floor");
}

public void decorate(){
System.out.println("Team2-----decorate");
}

public void paint(){
System.out.println("Team2-----paint");
}
};

Main.java

Java代码
public class Main   
{   
    public static void main(String[] args){   
        Template t = new Team1();   
        t.fitment();   
        Template t2 = new Team2();   
        t2.fitment();   
    }   
};  

相关推荐

    设计模式C++学习之模板方法模式(Template Method)

    在这个例子中,`AbstractClass`是模板类,定义了`templateMethod`模板方法,它调用了`primitiveOperation1`、`primitiveOperation2`以及组件(Component)的`operation`方法。`ConcreteComponentA`和`...

    Head First 设计模式 (八) 模板方法模式(Template Method pattern) C++实现

    在这个例子中,`AbstractClass`定义了`templateMethod`模板方法,其中`step1()`是具体实现,而`step2()`和`step3()`作为抽象方法由`ConcreteClass1`和`ConcreteClass2`这两个具体类来实现。这样,不同的具体类可以...

    C++设计模式编程中Template Method模板方法模式的运用

    void TemplateMethod() { PrimitiveOperation1(); PrimitiveOperation2(); } protected: virtual void PrimitiveOperation1() = 0; // 抽象方法 virtual void PrimitiveOperation2() = 0; // 抽象方法 ...

    template-method-demo 模板方法示例

    在"template-method-demo"这个示例中,我们可以预见到它将展示如何在Java中应用模板方法模式。这个压缩包可能包含以下内容: 1. 一个抽象类(例如:`AbstractClass`),它定义了模板方法。在这个类中,可能会有一个...

    C++设计模式课件3_Template Method_模板方法.pdf

    ### C++设计模式课件3_Template Method_模板方法 #### 模板方法设计模式解析 模板方法模式(Template Method Pattern)是一种行为型设计模式,它允许我们定义算法的骨架,并将部分步骤推迟到子类中实现。这种模式...

    模板方法模式(TemplateMethod)原理图

    模板方法模式是一种行为设计模式,它在一个方法中定义算法的骨架,将一些步骤延迟到子类中实现。 具体来说,模板方法模式的关键特点包括: 抽象类:在抽象类中定义一个模板方法,该方法给出了算法的框架。 具体...

    C++设计模式代码资源3_Template Method_模板方法.zip

    "模板方法"(Template Method)是设计模式中的一个经典概念,它属于行为设计模式,主要用在父类中定义一个算法的框架,允许子类在这个框架内重定义特定的步骤。这个模式通常用于代码复用和保持代码结构的一致性。 ...

    Template(模板模式)

    在模板模式中,一个抽象类公开定义了执行它的方法的方式,而将具体实现延迟到子类中。这种方式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 模板模式的核心结构包括抽象类(AbstractClass)...

    设计模式-模板方法模式ppt

    - **抽象类(Abstract Class)**:包含一个或多个抽象方法,并且有一个模板方法(template method)。模板方法通常被声明为final,这意味着它不能被子类覆盖。 - **具体操作(Concrete Operations)**:在抽象类中...

    设计模式--模板方法模式java例子

    在这个例子中,`templateMethod`是模板方法,它在`AbstractClass`中定义了算法的整体结构,而`step1`是一个需要子类实现的抽象方法,`step2`是可选的默认实现,`step3`是不能被子类重写的最终方法。 模板方法模式的...

    模板方法模式案例代码

    4. **模板方法(Template Method)**:定义了算法的基本步骤,调用各个步骤的方法,可以是抽象的也可以是具体的方法。 下面是一个简单的Java模板方法模式示例,以饮料制作过程为例: ```java public abstract ...

    设计模式-模板方法模式(讲解及其实现代码)

    在这个例子中,`AbstractClass` 是抽象类,`templateMethod` 是模板方法,`step1`、`step2` 和 `step3` 是基本方法,其中 `step2` 提供了一个默认实现,`step3` 是一个钩子方法,子类可以选择是否覆盖。`Concrete...

    TemplateMethod 模式与代码重构

    TemplateMethod(模板方法)设计模式是一种行为设计模式,它在面向对象编程中扮演着重要的角色。这个模式允许我们在抽象类中定义一个算法的框架,同时允许子类在不改变算法结构的情况下重写算法中的特定步骤。通过...

    模板方法模式例子

    2. 模板方法(TemplateMethod):这是核心方法,定义了算法的整体结构,调用了抽象方法和具体方法。 3. 具体方法(ConcreteMethod):这些方法在抽象类中已经完全实现,子类不需要关心这部分代码。 例如,假设我们...

    设计模式之模板方法模式

    3. **模板方法(Template Method)**:在抽象类中定义的,它是一个具体方法,负责组织和控制算法的流程。模板方法通常包含了业务逻辑的主要流程,并调用了其他基本方法。 4. **钩子方法(Hook Methods)**:可选的...

    模版方法模式TemplatePattern

    2. 模板方法(Template Method):这是一个具体的方法,定义了算法的骨架。这个方法由抽象类实现,它调用了基本方法来执行特定的步骤。模板方法通常声明为final,防止子类重写其结构。 3. 基本方法(Primitive ...

    TemplateMethod.rar

    标题“TemplateMethod.rar”暗示了这个压缩包包含的是关于Qt平台上实现模板方法设计模式的示例代码。Qt是一个跨平台的应用程序开发框架,常用于创建GUI程序,但也可用于非图形化的后台服务。 描述中的“模板方法...

    ios-iOS模板方法模式使用心得demo.zip

    4. 模板方法(Template Method):定义了算法的基本结构,包括一系列步骤,这些步骤可能包含直接调用的钩子方法。模板方法通常是不可变的,确保算法的总体流程不会被子类改变。 在iOS应用开发中,模板方法模式的...

    源码:阎宏设计模式光盘

    源代码清单(按照库排列) ...com.javapatterns.templatemethod 模板方法模式 com.javapatterns.uml 统一建模语言UML介绍 com.javapatterns.visitor 访问者模式 com.javapatterns.windowadapter 缺省适配模式 ...

Global site tag (gtag.js) - Google Analytics