Template

September 2, 2014
Author:Eric
Source:http://blog.wjin.org/posts/template.html
Declaration: this work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License. Creative Commons License

Template Method

Introduction

The template method pattern defines the skeleton of an algorithm in a method, deferring some steps to subclasses. Template method lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure.

According to above description, we can learn that factory method pattern is a special version of template method as it lets subclass make a decision to instantiate which class.

Example

Taking the same example in command pattern, this time I use template pattern to implement worker class. For different workers, they have the same workflow, that is read request from master process, analyse request, excute request and return result.

Code

Cpp

// abstract worker
class Worker
{
public:
    // template method, do not modify
    virtual void process() final {
        // hook for subclass
        hook();

        readRequest();
        analyseRequest();
        executeRequest();
        returnResult();
    }

    void readRequest()
    {
        cout << "IPC: read request from master process" << endl;
    }

    void analyseRequest()
    {
        cout << "Protocol Analysis: analyse request and store result to handle" << endl;
    }

    virtual void executeRequest() = 0;

    void returnResult()
    {
        cout << "Return: return result in buffer to master process" << endl;
    }

    virtual void hook() {}
};

// append log worker
class WorkerForLog : public Worker
{
public:
    void executeRequest()
    {
        cout << "Execute: open file and append log" << endl;
    }
};

// access database worker
class WorkerForDB : public Worker
{
public:
    void executeRequest()
    {
        cout << "Execute: open database and read tables" << endl;
    }
};

int main(int argc, const char* argv[])
{
    shared_ptr<Worker> log(new WorkerForLog());
    shared_ptr<Worker> db(new WorkerForDB());

    log->process();
    cout << endl;
    db->process();

    return 0;
}

Java

// abstract worker
abstract class Worker {

	// template method, do not modify
	public final void process() {
		// hook for subclass
		hook();

		readRequest();
		analyseRequest();
		executeRequest();
		returnResult();
	}

	public void readRequest() {
		System.out.println("IPC: read request from master process");
	}

	public void analyseRequest() {
		System.out
				.println("Protocol Analysis: analyse request and store result to handle");
	}

	public abstract void executeRequest();

	public void returnResult() {
		System.out.println("Return: return result in buffer to master process");
	}

	public void hook() {
	}
}

// append log worker
class WorkerForLog extends Worker {
	@Override
	public void executeRequest() {
		System.out.println("Execute: open file and append log");
	}
}

// access database worker
class WorkerForDB extends Worker {
	@Override
	public void executeRequest() {
		System.out.println("Execute: open database and read tables");
	}
}

public class Template {
	public static void main(String[] args) {
		Worker log = new WorkerForLog();
		Worker db = new WorkerForDB();

		log.process();
		System.out.println();
		db.process();
	}
}