Шаблонный метод (Template method)


Рабочее пространство приложения позволяет вам наследовать от класса или набора классов и создавать новое приложение, повторно используя большую часть кода существующего класса и перегружая один или несколько методов для того, чтобы приложение удовлетворяло вашим требованиям. Фундаментальной концепцией рабочего пространства приложения является Шаблонный Метод, который обычно прячется под оберткой и управляет приложением, вызывая различные методы базового класса (некоторые из них вы можете перегрузить при создании приложения).

Например, когда бы вы не создавали апплет, вы используете рабочее пространство приложения: вы наследуете от JApplet, а затем перегружаете init(). Механизм апплета (который является Шаблонным Методом) делает остальное включая рисование на экране, цикл обработки событий, слежение за изменением размера и т.п.

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

//: templatemethod:TemplateMethod.java
// Простая демонстрация Шаблонного Метода.
package templatemethod;

import junit.framework.*;

abstract class ApplicationFramework {
  
public ApplicationFramework() {
     
templateMethod(); // Опасность!
  
}
  
  
abstract void customize1();
  
  
abstract void customize2();
  
  
final void templateMethod() {
     
for (int i = 0; i < 5; i++) {
        
customize1();
         customize2
();
     
}
   }
}

// Создание нового "приложения":
class MyApp extends ApplicationFramework {
  
void customize1() {
     
System.out.print("Hello ");
  
}
  
  
void customize2() {
     
System.out.println("World!");
  
}
}

public class TemplateMethod extends TestCase {
  
MyApp app = new MyApp();
  
  
public void test() {
     
// Конструктор MyApp делает всю работу.
      // Здесь необходимо убедится, что все завершается
      // без выбрасывания исключений.
  
}
  
  
public static void main(String args[]) {
     
junit.textui.TestRunner.run(TemplateMethod.class);
  
}
}
// /:~

Конструктор базового класса отвечает за выполнение необходимой инициализации, а затем запускает "машину" (шаблонный метод), которая запускает приложение (в GUI приложении такой "машиной" является главный цикл событий). Клиентский программист просто предоставляет определение для методов customize1( ) и customize2( ), и "приложение" готово к запуску.

Упражнения

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