Template method in java example

Template method

Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure.

# Explanation

The general steps in stealing an item are the same. First, you pick the target, next you confuse him somehow and finally, you steal the item. However, there are many ways to implement these steps.

Template Method pattern outlines the general steps in the parent class and lets the concrete child implementations define the details.

In object-oriented programming, the template method is one of the behavioral design patterns identified by Gamma et al. in the book Design Patterns. The template method is a method in a superclass, usually an abstract superclass, and defines the skeleton of an operation in terms of a number of high-level steps. These steps are themselves implemented by additional helper methods in the same class as the template method.

Programmatic Example

Let’s first introduce the template method class along with its concrete implementations. To make sure that subclasses don’t override the template method, the template method (in our case method steal ) should be declared final , otherwise the skeleton defined in the base class could be overridden in subclasses.

@Slf4j public abstract class StealingMethod  protected abstract String pickTarget(); protected abstract void confuseTarget(String target); protected abstract void stealTheItem(String target); public final void steal()  var target = pickTarget(); LOGGER.info("The target has been chosen as <>.", target); confuseTarget(target); stealTheItem(target); > > @Slf4j public class SubtleMethod extends StealingMethod  @Override protected String pickTarget()  return "shop keeper"; > @Override protected void confuseTarget(String target)  LOGGER.info("Approach the <> with tears running and hug him!", target); > @Override protected void stealTheItem(String target)  LOGGER.info("While in close contact grab the <>'s wallet.", target); > > @Slf4j public class HitAndRunMethod extends StealingMethod  @Override protected String pickTarget()  return "old goblin woman"; > @Override protected void confuseTarget(String target)  LOGGER.info("Approach the <> from behind.", target); > @Override protected void stealTheItem(String target)  LOGGER.info("Grab the handbag and run away fast!"); > > 

Источник

Template method in java example

Предположим, нам поставили задачу написать программу, которая должна нарисовать трехцветный флаг России. При этом она будет действовать по следующему алгоритму:

  • нарисовать флагшток
  • нарисовать первую полосу белого цвета
  • нарисовать вторую полосу синего цвета
  • нарисовать третью полосу красного цвета

Наша программа делает то, что требуется. Далее заказчик попросил написать код для рисования еще одного трехцветного флага — флага Нидерландов.

Но, наш код ужасен! Мы не используем объектно-ориентированный подход, и у нас нарушен DRY-принцип — код дублируется.

Давайте создадим для каждого флага свой класс: RussianFlag и NetherlandsFlag. Рисование конкретным цветом вынесем в методы, которые поместим в класс Colors, что позволит избавиться от дублирования кода.

 class Colors < static void paintWhiteColor() < System.out.println("Полоса белого цвета нарисована"); >static void paintBlueColor() < System.out.println("Полоса синего цвета нарисована"); >static void paintRedColor() < System.out.println("Полоса красного цвета нарисована"); >> 
 class RussianFlag < void drawFlag() < drawFlagpole(); Colors.paintWhiteColor(); Colors.paintBlueColor(); Colors.paintRedColor(); >private void drawFlagpole() < System.out.println("Флагшток нарисован"); >> 
 class NetherlandsFlag < void drawFlag() < drawFlagpole(); Colors.paintRedColor(); Colors.paintWhiteColor(); Colors.paintBlueColor(); >private void drawFlagpole() < System.out.println("Флагшток нарисован"); >> 

Код уже стал лучше, но мы можем вынести рисование флагштока в отдельный класс Flagpole, что бы метод не дублировался. А уже от этого класса будут наследоваться классы для рисования конкретных флагов.

Внесем изменения в классы RussianFlag и NetherlandsFlag: добавим extends Flagpole и уберем метод drawFlagpole:

 class RussianFlag extends Flagpole < void drawFlag() < drawFlagpole(); Colors.paintWhiteColor(); Colors.paintBlueColor(); Colors.paintRedColor(); >> 
 class NetherlandsFlag extends Flagpole < void drawFlag() < drawFlagpole(); Colors.paintRedColor(); Colors.paintWhiteColor(); Colors.paintBlueColor(); >> 

Внезапно мы понимаем, что каждый раз действуем по одному и тому же алгоритму: рисуем флагшток, верхнюю часть флага, среднюю и нижнюю. Этот алгоритм неизменен для рисования флагов с тремя полосами. А что, если нам сделать методы для рисования полос флага абстрактными, а их реализацию делегировать (поручить) классам конкретных флагов? И даже сам алгоритм рисования флага поместить в абстрактный класс в метод drawFlag. А что бы его нельзя было переопределить (изменить) при наследовании, пометить его как final.

Класс Flagpole становится ненужным, поскольку рисование флагштока также можно перенести в абстрактный класс. Итак, класс AbstractThreeRowsFlag будет выглядеть следующим образом:

 abstract class AbstractThreeRowsFlag < abstract void drawUpperLevel(); abstract void drawMiddleLevel(); abstract void drawBottomLevel(); final void drawFlag() < drawFlagpole(); drawUpperLevel(); drawMiddleLevel(); drawBottomLevel(); >private void drawFlagpole() < System.out.println("Флагшток нарисован"); >> 

Метод drawFlag(), содержащий алгоритм рисования флага, является шаблонным методом. Он так называется потому, что задает скелет в виде последовательности шагов, которые будут переопределять (реализовывать), каждый по своему, наследники AbstractThreeRowsFlag. Его подклассы не смогут изменить последовательность шагов, т.к. шаблонный метод помечен, как final и не наследуется.

Как вы уже поняли, для рисования флагов мы только что использовали паттерн под названием «Шаблонный метод» (Template Method), благодаря которому мы избавились от дублирования кода, а так же повысили его универсальность и переиспользуемость.

Обратите внимание, не все методы в шаблонном методе являются абстрактными, например drawFlagpole (рисование флагштока). Из этого можно сделать вывод, что шаблонный метод не обязательно должен состоять только из абстрактных методов, которые необходимо переопределять в подклассах. Он может содержать переменные, какую-то внутреннюю логику и т. д. Но очень часто новички, читая материал по данному паттерну, ошибочно полагают, что шаблонный метод — это метод, который состоит только из абстрактных методов и ничего другого содержать не может. Это и не удивительно, в интернете полно статей с примерами таких методов, что сбивает с толку.

Вернемся к нашим флагам, классы для рисования которых уже выглядят так (про @Override можно прочитать в нашей прошлой статье):

 class RussianFlag extends AbstractThreeRowsFlag < @Override void drawUpperLevel() < Colors.paintWhiteColor(); >@Override void drawMiddleLevel() < Colors.paintBlueColor(); >@Override void drawBottomLevel() < Colors.paintRedColor(); >> 
 class NetherlandsFlag extends AbstractThreeRowsFlag < @Override void drawUpperLevel() < Colors.paintRedColor(); >@Override void drawMiddleLevel() < Colors.paintWhiteColor(); >@Override void drawBottomLevel() < Colors.paintBlueColor(); >> 

Теперь можно нарисовать флаг Югославии, Германии (добавив к нашему набору цветов необходимые: черный и желтый) и любые другие подобные трехцветные флаги, применяя ООП и максимально переиспользуя существующий код.

Источник

Template Method Design Pattern in Java

Template Method Design Pattern in Java

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Template Method is a behavioral design pattern. Template Method design pattern is used to create a method stub and deferring some of the steps of implementation to the subclasses.

Template Method Design Pattern

Template method defines the steps to execute an algorithm and it can provide default implementation that might be common for all or some of the subclasses. Let’s understand this pattern with an example, suppose we want to provide an algorithm to build a house. The steps need to be performed to build a house are — building foundation, building pillars, building walls and windows. The important point is that the we can’t change the order of execution because we can’t build windows before building the foundation. So in this case we can create a template method that will use different methods to build the house. Now building the foundation for a house is same for all type of houses, whether its a wooden house or a glass house. So we can provide base implementation for this, if subclasses want to override this method, they can but mostly it’s common for all the types of houses. To make sure that subclasses don’t override the template method, we should make it final.

Template Method Abstract Class

Since we want some of the methods to be implemented by subclasses, we have to make our base class as abstract class. HouseTemplate.java

package com.journaldev.design.template; public abstract class HouseTemplate < //template method, final so subclasses can't override public final void buildHouse()< buildFoundation(); buildPillars(); buildWalls(); buildWindows(); System.out.println("House is built."); >//default implementation private void buildWindows() < System.out.println("Building Glass Windows"); >//methods to be implemented by subclasses public abstract void buildWalls(); public abstract void buildPillars(); private void buildFoundation() < System.out.println("Building foundation with cement,iron rods and sand"); >> 

Template Method Concrete Classes

package com.journaldev.design.template; public class WoodenHouse extends HouseTemplate < @Override public void buildWalls() < System.out.println("Building Wooden Walls"); >@Override public void buildPillars() < System.out.println("Building Pillars with Wood coating"); >> 
package com.journaldev.design.template; public class GlassHouse extends HouseTemplate < @Override public void buildWalls() < System.out.println("Building Glass Walls"); >@Override public void buildPillars() < System.out.println("Building Pillars with glass coating"); >> 

Template Method Design Pattern Client

package com.journaldev.design.template; public class HousingClient < public static void main(String[] args) < HouseTemplate houseType = new WoodenHouse(); //using template method houseType.buildHouse(); System.out.println("************"); houseType = new GlassHouse(); houseType.buildHouse(); >> 

Notice that client is invoking the template method of base class and depending of implementation of different steps, it’s using some of the methods from base class and some of them from subclass. Output of the above program is:

Building foundation with cement,iron rods and sand Building Pillars with Wood coating Building Wooden Walls Building Glass Windows House is built. ************ Building foundation with cement,iron rods and sand Building Pillars with glass coating Building Glass Walls Building Glass Windows House is built. 

Template Method Class Diagram

template method design pattern, template design pattern

Template Method Design Pattern in JDK

  • All non-abstract methods of java.io.InputStream, java.io.OutputStream, java.io.Reader and java.io.Writer.
  • All non-abstract methods of java.util.AbstractList, java.util.AbstractSet and java.util.AbstractMap.

Template Method Design Pattern Important Points

  1. Template method should consists of certain steps whose order is fixed and for some of the methods, implementation differs from base class to subclass. Template method should be final.
  2. Most of the times, subclasses calls methods from super class but in template pattern, superclass template method calls methods from subclasses, this is known as Hollywood Principle — “don’t call us, we’ll call you.”.
  3. Methods in base class with default implementation are referred as Hooks and they are intended to be overridden by subclasses, if you want some of the methods to be not overridden, you can make them final, for example in our case we can make buildFoundation() method final because if we don’t want subclasses to override it.

Thats all for template method design pattern in java, I hope you liked it.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Источник

Читайте также:  Цвета
Оцените статью