Где мы должны использовать Шаблонный метод - pattern?

StackOverflow https://stackoverflow.com/questions/1553856

Вопрос

Кто-нибудь может сообщить мне несколько примеров ситуаций, в которых следует использовать шаблонный метод - pattern?

Дайте мне какое-нибудь реальное применение из вашего собственного опыта.

(До сих пор я находил это полезным только для отображения данных на уровне DA.Извините!!!)

Это было полезно?

Решение

Я попытался привести вам несколько реальных примеров и некоторые распространенные ситуации, в которых следует использовать шаблонный метод pattern.

  • Когда вы хотите, чтобы ваша программа была "Открыта для расширения”, а также “Закрыта для модификации”. Это означает, что поведение модуля может быть расширено таким образом, что мы можем заставить модуль вести себя по-новому по мере изменения требований приложения или для удовлетворения потребностей новых приложений.Однако исходный код такого модуля является неприкосновенным.Никому не разрешается вносить в него изменения в исходный код.В следующем примере вы можете добавить новый способ расчета заработной платы (например, удаленное обучение) без изменения предыдущих кодов.

    public abstract class Salary {
    
       public final void calculate() {
            System.out.println("First shared tasks is done.");
            getBaseSalary();
            System.out.println("Second shared tasks is done.");
       }
    
       public abstract void getBaseSalary();
    
    }
    
    public class Hourly extends Salary {
    
        @Override
        public void getBaseSalary() {
            System.out.println("Special Task is done.");
        }
    
    }
    
    public class Test {
    
        public static void main(String[] args) {
            Salary salary = ....
            salary.calculate();
        }
    }
    
  • Когда вы сталкиваетесь со многими одинаковыми строками кодов, которые дублируются из-за отсрочки всего лишь некоторых шагов вашего алгоритма. Когда вы реализуете содержимое метода или функции, вы можете найти некоторые разделы вашего кода, которые варьируются от одного типа к другому.Особенностью этих разделов является то, что можно переопределить или модифицировать эти разделы метода или функции без изменения основной структуры алгоритма (метода или функции).Например, если вы хотите решить эту проблему без этого шаблона, вы столкнетесь с этим образцом:

функция 0:функция 1:...Функция N:

1       1               1
2       2               2
...     ...             ...
5       6               n
3       3               3
4       4               4
...     ...             ...

Как вы можете видеть, коды разделов 5, 6, n отличаются от одной функции к другой, однако у вас есть общие разделы, такие как 1,2,3,4, которые дублируются.Давайте рассмотрим решение с одной из известных библиотек Java.

public abstract class InputStream implements Closeable {

    public abstract int read() throws IOException;

    public int read(byte b[], int off, int len) throws IOException {
        ....

        int c = read();
        ....
    }

    ....

}

public class ByteArrayInputStream extends InputStream {  

    ...

    public synchronized int read() {
        return (pos < count) ? (buf[pos++] & 0xff) : -1;
        }
    ...
}
  • Когда вы, как разработчик фреймворка, хотите, чтобы ваши клиенты просто использовали любой исполняемый код, который передается в качестве аргумента вашему фреймворку, который, как ожидается, перезвонит (выполнит) этот аргумент в данный момент времени. Это выполнение может быть немедленным, как при синхронном обратном вызове, или это может произойти позже, как при асинхронном обратном вызове.Давайте рассмотрим один из известных из них.

    public abstract class HttpServlet extends GenericServlet 
        implements java.io.Serializable  {
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
            ...
        }
    
    protected void service(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {
            ....
            doGet(req, resp);
            ...
        }
        ...
    }
    }
    
    public class MyServlet extends HttpServlet {
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
    
                //do something
            ...
        }
        ...
    }
    

Другие советы

A Шаблон метода шаблон предоставляет скелет для выполнения любого вида алгоритма или операции, и это позволяет подклассам переопределять часть логики.

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

Примеры:

  • java.util.Список абстракций
  • Методы doGet и doPost сервлета
  • Метод onMessage MDB для отправки сообщений
  • Класс действия Struts
  • Классы доступа к данным Spring

Минусы:Ограничивает вас одним наследованием в Java.

Применение этого Шаблонный Метод узор имеет две основные характеристики:

  1. Существует базовый класс (в Java, один только с protected конструкторы и необязательно объявляются как abstract), который будет подклассом в клиентском коде.
  2. Есть такие две группы методов определенный в базовом классе:а) один или несколько шаблонные методы (обычно только один) и один или несколько примитивная операция методы (обычно более одного).Каждый шаблонный метод представляет собой операцию высокого уровня, реализованную в самом базовом классе в терминах примитивных операций, которые предназначены для реализации / переопределения в каждом конкретном подклассе.Обычно метод шаблона является общедоступным и не переопределяемым (final, на Java);документация его API должна точно указывать, какие примитивные методы работы он вызывает и когда (то есть он должен описывать "алгоритм").Примитивный операционный метод, который представляет собой шаг в алгоритме, должен быть закрытым, но переопределяемым (protected, на Java), и может быть двух типов:а) абстрактный метод, который должен быть реализован в подклассе;б) метод с реализацией по умолчанию / пустой, который мочь быть переопределенным в подклассе.

Одним из хороших примеров в Java 6 SDK является execute() метод проведения javax.swing.SwingWorker класс (это public final void способ).В этом случае примитивными методами работы являются doInBackground(), process(List), и done().Первый из них является абстрактным и поэтому требует реализации в подклассе;он вызывается методом template в фоновом потоке.Два других имеют пустые реализации и при необходимости могут быть переопределены в подклассе;они вызываются во время и в конце обработки, соответственно, в EDT (поток отправки событий Swing), чтобы разрешить обновления пользовательского интерфейса.

По моему собственному опыту, я иногда использовал этот шаблон.Одним из таких случаев был базовый класс Java, реализующий java.util.Iterator интерфейс, где next() был шаблонным методом, и существовал только один примитивный операционный метод, ответственный за создание экземпляра определенного класса сущностей домена (он предназначался для использования при переборе списка постоянных объектов сущностей домена с использованием JDBC).Лучшим примером в том же приложении был базовый класс, в котором метод template реализовал многоступенчатый алгоритм, предназначенный для заполнения "экрана обслуживания бизнес-объекта" (с использованием Swing) из заданного списка постоянных объектов;методы примитивных операций были вызваны для 1) очистки текущего состояния экрана и 2) добавления объекта в табличное представление внутри экрана;необязательно, другие примитивные операции вызывались из метода template, если экран был доступен для редактирования.

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

Самое важное в методе template заключается в том, что вы должны определить серию абстрактных методов в виде шагов или алгоритма и позволить подклассу заменить эти методы конкретной реализацией.

Я подал заявку в одну из программ генерации документов.

public abstract DocumentGenerator() 
{
   generateHeader();
   generateBody();
   generateDetails();
}
public HTMLDocGenerator : DocumentGenerator()
{
   public override generateBody()
   {
     //generate as in html format
   }
}

У вас может быть другая реализация, такая как генератор PDF, генератор CSV, и значение здесь в том, что они соответствуют алгоритму (generate -> header, body, details).

Шаблонный шаблон следует использовать, когда существует алгоритм со многими реализациями.Алгоритм определен в функции базового класса, а реализация осуществляется базовым классом и подклассами.Подробное объяснение с примером в реальном времени приведено в http://preciselyconcise.com/design_patterns/templatemethod.php

Я приведу один пример из реального мира, где я использовал некоторые шаблонные методы.

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

Одной из причин такого разнообразия вариантов запущенного алгоритма была онлайн- или оффлайн-функциональность программного обеспечения, которое управляло нашим инструментом.Автономный вариант обеспечивал более богатый отладочный / диагностический вывод и сохранял локальную систему координат для некоторых пикселей изображения, в то время как онлайн-вариант сохранял абсолютное координатное пространство и поддерживал проблемы, характерные для работающего инструмента со всей его робототехникой, а что нет.Другое перечисление определило выбор среди набора классификаторов, которые мы также использовали для некоторого машинного обучения, поскольку разные классификаторы обучались на разных наборах данных, которые в остальном проходили идентично через тело кода, но должны были интерпретироваться по-разному на основе некоторых определяющих условий создания этих данных.

Я полагаю, что такого рода вариант использования, который у меня был, возник из того, что было названо отверстие посередине проблема.

Я использовал метод шаблона для бизнес-логики, где ряд компонентов совместно использовали один и тот же процесс, но реализация была немного иной.

Шаблонный метод определяет базовую структуру алгоритма, но переносит определенные шаги и детали на подклассы.Структура и ход выполнения алгоритма остаются статичными, но детали шагов перенесены на подклассы.

Я использовал шаблонный метод Pattern для подготовки содержимого документа.Существовало много различных видов документов, каждый из которых имел свои собственные небольшие модификации.Однако основной процесс подготовки документа был одинаковым для всех.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top