From 0776427f49975b494a218e3144be078a7ce714bf Mon Sep 17 00:00:00 2001 From: Calum Robertson Date: Thu, 19 Sep 2013 19:08:22 +0100 Subject: [PATCH 1/2] Added the Template Method Pattern. --- authors.md | 1 + chapters/design_patterns/template_method.md | 45 +++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 chapters/design_patterns/template_method.md diff --git a/authors.md b/authors.md index be4922c..7876aa2 100644 --- a/authors.md +++ b/authors.md @@ -21,6 +21,7 @@ The following people are totally rad and awesome because they have contributed r * Frederic Hemberger * Mike Hatfield *oakraven13@gmail.com* * [Anton Rissanen](http://github.com/antris) *hello@anton.fi* +* Calum Robertson *http://github.com/randusr836* * ...You! What are you waiting for? Check out the [contributing](/contributing) section and get cracking! # Developers diff --git a/chapters/design_patterns/template_method.md b/chapters/design_patterns/template_method.md new file mode 100644 index 0000000..607be35 --- /dev/null +++ b/chapters/design_patterns/template_method.md @@ -0,0 +1,45 @@ +--- +layout: recipe +title: Template Method Pattern +chapter: Design Patterns +--- +## Problem + +You need to execute a series of steps according to some algorithm or recipe and wish to provide the implementation for any of the steps. + +## Solution + +Use the Template Method to describe each step in a superclass, delegating the implementation of each step to a subclass. + +For example, imagine you wish to model various types of document and each one may contain a header and a body. + +{% highlight coffeescript %} +class Document + produceDocument: -> + @produceHeader() + @produceBody() + + produceHeader: -> + produceBody: -> + +class DocWithHeader extends Document + produceHeader: -> + console.log "Producing header for DocWithHeader" + + produceBody: -> + console.log "Producing body for DocWithHeader" + +class DocWithoutHeader extends Document + produceBody: -> + console.log "Producing body for DocWithoutHeader" + +doc1 = new DocWithHeader +doc1.produceDocument() + +doc2 = new DocWithoutHeader +doc2.produceDocument() +{% endhighlight %} + +## Discussion + +In this example, there are two steps, one for producing a document header and the second for producing the document body; these two steps are given empty implementations in the superclass. The DocWithHeader implements both the body and header steps, whereas the DocWithoutHeader only impements the body step. From 198eed36fca85a819aac55ee534432d4dfcb0b9c Mon Sep 17 00:00:00 2001 From: Calum Robertson Date: Fri, 20 Sep 2013 21:39:13 +0100 Subject: [PATCH 2/2] Changes after feedback. Wrote a little about polymorphism being used in the pattern. Described in greater detail the concepts of the algorithm structure and the specification of algorithm step behaviour. --- chapters/design_patterns/template_method.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/chapters/design_patterns/template_method.md b/chapters/design_patterns/template_method.md index 607be35..31fe475 100644 --- a/chapters/design_patterns/template_method.md +++ b/chapters/design_patterns/template_method.md @@ -5,13 +5,13 @@ chapter: Design Patterns --- ## Problem -You need to execute a series of steps according to some algorithm or recipe and wish to provide the implementation for any of the steps. +Define the structure of an algorithm as a series of high-level steps, making it possible to specify the behaviour of each step, giving rise to a family of algorithms that have the same structure but different behaviours. ## Solution -Use the Template Method to describe each step in a superclass, delegating the implementation of each step to a subclass. +Use the Template Method to describe the algorithm structure in a superclass, delegating the implementation of some steps to one or more concrete subclasses. -For example, imagine you wish to model various types of document and each one may contain a header and a body. +For example, imagine you wish to model the production of various types of document and each one may contain a header and a body. {% highlight coffeescript %} class Document @@ -33,13 +33,12 @@ class DocWithoutHeader extends Document produceBody: -> console.log "Producing body for DocWithoutHeader" -doc1 = new DocWithHeader -doc1.produceDocument() - -doc2 = new DocWithoutHeader -doc2.produceDocument() +docs = [new DocWithHeader, new DocWithoutHeader] +doc.produceDocument() for doc in docs {% endhighlight %} ## Discussion -In this example, there are two steps, one for producing a document header and the second for producing the document body; these two steps are given empty implementations in the superclass. The DocWithHeader implements both the body and header steps, whereas the DocWithoutHeader only impements the body step. +In this example, the algorithm consists of two steps describing document production: one for producing a document header and the second for producing the document body. An empty method implementation for each step is present in the superclass and polymorphism is exploited such that each concrete subclass can provide a different implementation for a step by overriding a step method. In this example,the DocWithHeader implements both the body and header steps, whereas the DocWithoutHeader only implements the body step. + +The production of different types of document is then straightforward when document objects are stored in an array, and it is then a simple of matter of iterating over each document object and calling its produceDocument method. \ No newline at end of file