Skeleton of GOF's Design Pattern


TEMPLATEMETHODの骸骨

TEMPLATEMETHOD

このパターンは、基本的な振る舞いの記述は、抽象クラスにテンプレートとして定義し、目的によって内容の記述を変えなければならない部分をサブクラスで定義します。

TEMPLATEMETHOD は、コードを再利用するための基本的な手法です。


■ 『TEMPLATEMETHODの骸骨』の構造


■ 『TEMPLATEMETHODの骸骨』 プログラム・コード

□ Java2版
// Copyright(C) 2000-2003 Yoshinori Oota All rights reserved.

public class TemplateMethodSample { 
    static public void main(String[] args) { 
        ConcreteClass aClass = new ConcreteClass();
        aClass.TemplateMethod("yoshinori oota"); 
    } 
}

abstract class AbstractClass { 
    public void TemplateMethod(String value) { 
        PrimitiveOperation2( PrimitiveOperation1(value) ); 
    }
    // 文字列処理をサブクラスで定義
    abstract protected String PrimitiveOperation1(String value);
    // 文字列の表示方法をサブクラスで定義
    abstract protected void PrimitiveOperation2(String value); 
}

class ConcreteClass extends AbstractClass { 
    protected String PrimitiveOperation1(String value) { 
        return value.toUpperCase(); 
    }
    protected void PrimitiveOperation2(String value) { 
        System.out.println(value); 
    }
}

○ C++版
// Copyright(C) 2003 Yoshinori Oota All rights reserved.

#include <cctype>
#include <string>
#include <iostream>
using namespace std;

class AbstractClass {
public:
    AbstractClass();
    virtual ~AbstractClass();
    void TemplateMethod(const string& value);
protected:
    virtual string PrimitiveOperation1(const string& value) = 0;
    virtual void PrimitiveOperation2(const string& value) = 0;
};

class ConcreteClass : public AbstractClass {
public:
    ConcreteClass();
    virtual ~ConcreteClass();
protected:
    virtual string PrimitiveOperation1(const string& value);
    virtual void PrimitiveOperation2(const string& value);
};


AbstractClass::AbstractClass() { }
AbstractClass::~AbstractClass() { }
void AbstractClass::TemplateMethod(const string& value) {
    PrimitiveOperation2( PrimitiveOperation1(value) );
}
ConcreteClass::ConcreteClass() { }
ConcreteClass::~ConcreteClass() { }
string ConcreteClass::PrimitiveOperation1(const string& value) {
    string tmp("");
    string::const_iterator it = value.begin();
    while (it != value.end()) {
        tmp += (char)toupper((int)(*it));
        ++it;
    }
    return tmp;
}
void ConcreteClass::PrimitiveOperation2(const string& value) {
    cout << value << endl;
}


int main() {
    ConcreteClass* aClass = new ConcreteClass();
    aClass->TemplateMethod("yoshinori oota");
    delete aClass;
}

○ C版
/* Copyright(C) 2009 Yoshinori Oota All rights reserved. */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>


/* AbstractClass Interface */
struct AbstractClass {
    void (*TemplateMethod)(struct AbstractClass* pthis ,char* str);
    char* (*PrimitiveOperation1)(char* str);
    void (*PrimitiveOperation2)(char* str);
};
struct AbstractClass* New_AbstractClass();
void Delete_AbstractClass(struct AbstractClass* abstract);
void AbstractClass_TemplateMethod(struct AbstractClass* abstract ,char* str);
char* Concrete_PrimitiveOperation1(char* str);
void Concrete_PrimitiveOperation2(char* str);


/* AbstractClass Implementation */
struct AbstractClass* New_AbstractClass() {
    struct AbstractClass* abstract = NULL;
    abstract = (struct AbstractClass*)malloc(sizeof(struct AbstractClass));
    abstract->TemplateMethod = &AbstractClass_TemplateMethod;
    abstract->PrimitiveOperation1 = &Concrete_PrimitiveOperation1;
    abstract->PrimitiveOperation2 = &Concrete_PrimitiveOperation2;
    return abstract;
}

void Delete_AbstractClass(struct AbstractClass* abstract) {
    if (abstract == NULL) {
        return;
    }
    free(abstract);
    abstract = NULL;
    return;
}

void AbstractClass_TemplateMethod(struct AbstractClass* abstract ,char* str) {
    char* result = NULL;
    result = abstract->PrimitiveOperation1(str);
    abstract->PrimitiveOperation2(result);
    free(result);
    return;
}

char* Concrete_PrimitiveOperation1(char* str) {
    int i = 0;
    int len = 0;
    char* buf = NULL;
    char* tmp = NULL;

    len = strlen(str);
    buf = (char*)malloc(len+1);

    tmp = buf;
    for (; i < len; ++i ,++buf ,++str) {
        *buf = (char)toupper((int)(*str));
    }
    *buf = '\0';
    return tmp;
}

void Concrete_PrimitiveOperation2(char* str) {
    printf("%s\n" ,str);
    return;
}


int main() {
    struct AbstractClass* abstract = NULL;

    abstract = New_AbstractClass();
    abstract->TemplateMethod(abstract ,"yoshinori oota");
    Delete_AbstractClass(abstract);

    return 0;
}


改訂履歴

2009.2.22 C言語版を追加
     
     

ご意見、ご感想はこちらまで。

Copyright(C) 2000-2009 Yoshinori Oota All rights reserved.

本ホームページのリンクは自由です。複製、転載される場合は、必ず著者までご連絡をください。