{"id":973,"date":"2025-12-03T09:00:00","date_gmt":"2025-12-02T22:00:00","guid":{"rendered":"https:\/\/jm.armijo.au\/dev\/?p=973"},"modified":"2025-12-02T22:23:16","modified_gmt":"2025-12-02T11:23:16","slug":"template-method-design-pattern-and-alternatives","status":"publish","type":"post","link":"https:\/\/jm.armijo.au\/dev\/blog\/2025\/12\/03\/template-method-design-pattern-and-alternatives\/","title":{"rendered":"Template Method Design Pattern And Alternatives"},"content":{"rendered":"\n<p>I cannot deny that the Template Method Design Pattern is one of my favourites, mainly because it&#8217;s so simple and helps us get rid of duplicated code, but it also has some downsides. In this article, I&#8217;ll give you a concrete real-life example of this design pattern in action, and what some alternatives are.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Solving A Real Problem<\/h3>\n\n\n\n<p>My team provides a feature that allows customers to download some of their data to CSV or XLSX files. There are four types of data that they can download, and given their differences, they are implemented in four different ways, or flows.<\/p>\n\n\n\n<p>We wanted to improve the way in which this data was downloaded, but it soon became clear that we needed to refactor the code we had before extending it.<\/p>\n\n\n\n<p>Initially, I thought that all four download flows would be very different, but it turns out there was a single algorithm that could describe all of them:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Get context data<\/li>\n\n\n\n<li>Get data to be downloaded<\/li>\n\n\n\n<li>Save data to file to be downloaded<\/li>\n\n\n\n<li>Upload file to the cloud<\/li>\n<\/ul>\n\n\n\n<p>So, I refactored one flow at a time, making the algorithm super explicit in each of them. I ended up with four files like this.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nclass DownloadFlowOne\n  def run\n    context_data = get_context_data\n    data = get_data(context_data)\n    file = save_data(data)\n    upload_file(file)\n  end\n\n  private\n\n  # I'll let you imagine the code of the\n  # methods below :)\n\n  def get_context_data; end\n  def get_data(context_data); end \n  def save_data(data); end\n  def upload_file(file); end\n\n  # Other support methods were also needed\n  def format_filename; end\n  def update_upload_progress; end\n  def send_analytics; end\nend\n<\/pre><\/div>\n\n\n<p>It turns out that most of the methods were very similar between the flow. Unsurprisingly, the main differences were on the <code>get_data<\/code> and <code>save_data<\/code> methods, as the data to be downloaded is different for each flow.<\/p>\n\n\n\n<p>Having confirmed that all flows are essentially the same, implementing the Template Method Design Pattern becomes really easy.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Template Method Design Pattern<\/h3>\n\n\n\n<p>To implement the Template Method Design Pattern, we need a class that clearly describes the steps of an algorithm, but not the implementation. Then, subclasses inherit from the template class and implement the steps of the algorithm.<\/p>\n\n\n\n<p>In my case, I created a Template class as shown below. Note that this class not only describes the algorithm, but it also implements all the common functionality. The only things that are explicitly undefined are the <code>get_data<\/code> and <code>save_data<\/code> methods:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: ruby; gutter: false; title: ; notranslate\" title=\"\">\nclass Template\n  def run\n    context_data = get_context_data\n    data = get_data(context_data)\n    file = save_data(data)\n    upload_file(file)\n  end\n\n  private\n\n  def get_data(context_data)\n    raise &quot;Implement in subclass&quot;\n  end\n\n  def save_data(data)\n    raise &quot;Implement in subclass&quot;\n  end\n\n  # These methods are implemented here\n  def get_context_data; end\n  def upload_file(file); end\n  def format_filename; end\n  def update_upload_progress; end\n  def send_analytics; end\nend\n<\/pre><\/div>\n\n\n<p>And then, we just create the flow classes with the code that is different from each other:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: ruby; gutter: false; title: ; notranslate\" title=\"\">\nclass DownloadFlowOne &lt; Template\n  def get_data(context_data)\n    # Concrete implementation for DownloadFlowOne\n  end\n\n  def save_data(data)\n    # Concrete implementation for DownloadFlowOne\n  end\nend\n<\/pre><\/div>\n\n\n<p>Although this works fine, I was not happy with it. When we want to download some data, we invoke <code>run<\/code> on classes <code>DownloadFlowOne<\/code>, <code>DownloadFlowTwo<\/code>, and so on. However, if we inspect the code of these classes, the algorithm is hidden. And on top of that, whenever we change the base Template class, we propagate the change to all children by default. This is both the advantage and disadvantage of this approach.<\/p>\n\n\n\n<p>So, I started thinking about alternatives to this.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Including Modules<\/h3>\n\n\n\n<p>Some languages, like Ruby, also allow using modules to include code in classes. This is a very flexible and powerful approach, which even helps as a workaround when multiple inheritance is not supported by the language.<\/p>\n\n\n\n<p>We can take advantage of this and, instead of inheriting from the Template class, we could turn it into a module and import it into our specific classes. Something like:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: ruby; gutter: false; title: ; notranslate\" title=\"\">\nclass DownloadTypeOne\n  include CommonModule\n\n  def get_data(context_data)\n    # Concrete implementation for Type One Downloads\n  end\n\n  def save_data(data)\n    # Concrete implementation for Type One Downloads\n  end\nend\n<\/pre><\/div>\n\n\n<p>In practice, this is the same as doing the Template Method Design Pattern, only that we do inheritance through module inclusion.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Composition<\/h3>\n\n\n\n<p>Whenever we want to avoid inheritance, composition is usually the best bet. The core idea of composition is to have different classes collaborate between them. One way of doing that is by passing an instance of a class by argument, so we can delegate tasks to it.<\/p>\n\n\n\n<p>In our example, we&#8217;d have to create a <code>DownloadAny<\/code> class that, just like the template class, implements all the common logic for all download flows. The important difference is that this class receives an object to which it delegates methods <code>get_data<\/code> and <code>save_data<\/code>.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: ruby; gutter: false; title: ; notranslate\" title=\"\">\nclass DownloadAny\n  def run(delegate)\n    context_data = get_context_data\n    data = delegate.get_data(context_data)\n    file = delegate.save_data(data)\n    upload_file(file)\n  end\n\n  private\n\n  # These methods are implemented here\n  def get_context_data; end\n  def upload_file(file); end\n  def format_filename; end\n  def update_upload_progress; end\n  def send_analytics; end\nend\n<\/pre><\/div>\n\n\n<p>And now we need to implement delegate classes instead, which have the same code as before, except that they do not inherit from the Template class. Usually, these classes would implement an interface. In languages like Ruby, though, we must rely on duck-typing.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: ruby; gutter: false; title: ; notranslate\" title=\"\">\nclass FlowOneDelegate\n  def get_data(context_data)\n    # Concrete implementation for DownloadFlowOne\n  end\n\n  def save_data(data)\n    # Concrete implementation for DownloadFlowOne\n  end\nend\n<\/pre><\/div>\n\n\n<p>Finally, to execute a specific download flow, we pass an instance to our <code>DownloadAny<\/code> class:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\ndelegate = FlowOneDelegate.new\nDownloadAny.new.run(delegate)\n<\/pre><\/div>\n\n\n<p>Unlike with the Template Method Design Pattern, we directly invoke the class that has the main algorithm, at the cost of hiding the concrete implementation of the Delegate classes.<\/p>\n\n\n\n<p>The advantage, however, is that changes to the main class are easier to control. Callers choose to use <code>DownloadAny<\/code>, and if changes to it would cause issues for the callers, we can switch to a different class instead. This is harder when the behaviour lives in a base class through inheritance.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">What To Choose<\/h3>\n\n\n\n<p>All the options presented in this article are valid approaches to avoid repeating identical flows. They are just different. Which one we choose depends on what we want to achieve.<\/p>\n\n\n\n<p>The Template Method Design Pattern approach is ideal if we want to avoid injecting dependencies to delegate the core logic, or if having a single class that handles all cases was not practical.<\/p>\n\n\n\n<p>Instead, composition is great at separating concerns and making testing easier as long as we are fine passing dependencies and invoking the same class (with the right dependency) for all use cases.<\/p>\n\n\n\n<p>Happy coding!<br>Jos\u00e9 Miguel<\/p>\n\n\n\n<p><em>Share if you find this content useful, and Follow me on\u00a0<a href=\"http:\/\/www.linkedin.com\/comm\/mynetwork\/discovery-see-all?usecase=PEOPLE_FOLLOWS&amp;followMember=jmarmijo\">LinkedIn<\/a>\u00a0to be notified of new articles.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I cannot deny that the Template Method Design Pattern is one of my favourites, mainly because it&#8217;s so simple and helps us get rid of duplicated code, but it also has some downsides. In this article, I&#8217;ll give you a concrete real-life example of this design pattern in action, and what some alternatives are. Solving [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":991,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-973","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/jm.armijo.au\/dev\/wp-json\/wp\/v2\/posts\/973","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jm.armijo.au\/dev\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jm.armijo.au\/dev\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jm.armijo.au\/dev\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/jm.armijo.au\/dev\/wp-json\/wp\/v2\/comments?post=973"}],"version-history":[{"count":17,"href":"https:\/\/jm.armijo.au\/dev\/wp-json\/wp\/v2\/posts\/973\/revisions"}],"predecessor-version":[{"id":990,"href":"https:\/\/jm.armijo.au\/dev\/wp-json\/wp\/v2\/posts\/973\/revisions\/990"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/jm.armijo.au\/dev\/wp-json\/wp\/v2\/media\/991"}],"wp:attachment":[{"href":"https:\/\/jm.armijo.au\/dev\/wp-json\/wp\/v2\/media?parent=973"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jm.armijo.au\/dev\/wp-json\/wp\/v2\/categories?post=973"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jm.armijo.au\/dev\/wp-json\/wp\/v2\/tags?post=973"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}