Шаблонный метод на Java
Шаблонный метод — это поведенческий паттерн, задающий скелет алгоритма в суперклассе и заставляющий подклассы реализовать конкретные шаги этого алгоритма.
Сложность:
Популярность:
Применимость: Шаблонные методы можно встретить во многих библиотечных классах Java. Разработчики создают их, чтобы позволить клиентам легко и быстро расширять стандартный код при помощи наследования.
Примеры Шаблонных методов в стандартных библиотеках Java:
-
Все не-абстрактные методы классов
java.io.InputStream,java.io.OutputStream,java.io.Readerиjava.io.Writer. -
Все не-абстрактные методы классов
java.util.AbstractList,java.util.AbstractSetиjava.util.AbstractMap. -
javax.servlet.http.HttpServlet, все методыdoXXX()по умолчанию возвращают HTTP-код 405 "Method Not Allowed". Однако вы можете переопределить их при желании.
Признаки применения паттерна: Класс заставляет своих потомков реализовать методы-шаги, но самостоятельно реализует структуру алгоритма.
Переопределение шагов алгоритма
Социальные сети предоставляют собственные методы API для авторизации, постинга и выхода, но общий процесс для всех сетей совпадает.
networks
networks/Network.java: Базовый класс социальной сети
package refactoring_guru.template_method.example.networks; /** * Базовый класс социальной сети. */ public abstract class Network { String userName; String password; Network() {} /** * Публикация данных в любой сети. */ public boolean post(String message) { // Проверка данных пользователя перед постом в соцсеть. Каждая сеть для // проверки использует разные методы. if (logIn(this.userName, this.password)) { // Отправка данных. boolean result = sendData(message.getBytes()); logOut(); return result; } return false; } abstract boolean logIn(String userName, String password); abstract boolean sendData(byte[] data); abstract void logOut(); } networks/Facebook.java: Конкретная социальная сеть
package refactoring_guru.template_method.example.networks; /** * Класс социальной сети. */ public class Facebook extends Network { public Facebook(String userName, String password) { this.userName = userName; this.password = password; } public boolean logIn(String userName, String password) { System.out.println("\nChecking user's parameters"); System.out.println("Name: " + this.userName); System.out.print("Password: "); for (int i = 0; i < this.password.length(); i++) { System.out.print("*"); } simulateNetworkLatency(); System.out.println("\n\nLogIn success on Facebook"); return true; } public boolean sendData(byte[] data) { boolean messagePosted = true; if (messagePosted) { System.out.println("Message: '" + new String(data) + "' was posted on Facebook"); return true; } else { return false; } } public void logOut() { System.out.println("User: '" + userName + "' was logged out from Facebook"); } private void simulateNetworkLatency() { try { int i = 0; System.out.println(); while (i < 10) { System.out.print("."); Thread.sleep(500); i++; } } catch (InterruptedException ex) { ex.printStackTrace(); } } } networks/Twitter.java: Ещё одна конкретная социальная сеть
package refactoring_guru.template_method.example.networks; /** * Класс социальной сети. */ public class Twitter extends Network { public Twitter(String userName, String password) { this.userName = userName; this.password = password; } public boolean logIn(String userName, String password) { System.out.println("\nChecking user's parameters"); System.out.println("Name: " + this.userName); System.out.print("Password: "); for (int i = 0; i < this.password.length(); i++) { System.out.print("*"); } simulateNetworkLatency(); System.out.println("\n\nLogIn success on Twitter"); return true; } public boolean sendData(byte[] data) { boolean messagePosted = true; if (messagePosted) { System.out.println("Message: '" + new String(data) + "' was posted on Twitter"); return true; } else { return false; } } public void logOut() { System.out.println("User: '" + userName + "' was logged out from Twitter"); } private void simulateNetworkLatency() { try { int i = 0; System.out.println(); while (i < 10) { System.out.print("."); Thread.sleep(500); i++; } } catch (InterruptedException ex) { ex.printStackTrace(); } } } Demo.java: Клиентский код
package refactoring_guru.template_method.example; import refactoring_guru.template_method.example.networks.Facebook; import refactoring_guru.template_method.example.networks.Network; import refactoring_guru.template_method.example.networks.Twitter; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; /** * Демо-класс. Здесь всё сводится воедино. */ public class Demo { public static void main(String[] args) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); Network network = null; System.out.print("Input user name: "); String userName = reader.readLine(); System.out.print("Input password: "); String password = reader.readLine(); // Вводим сообщение. System.out.print("Input message: "); String message = reader.readLine(); System.out.println("\nChoose social network for posting message.\n" + "1 - Facebook\n" + "2 - Twitter"); int choice = Integer.parseInt(reader.readLine()); // Создаем сетевые объекты и публикуем пост. if (choice == 1) { network = new Facebook(userName, password); } else if (choice == 2) { network = new Twitter(userName, password); } network.post(message); } } OutputDemo.txt: Результат выполнения
Input user name: Jhonatan Input password: qswe Input message: Hello, World! Choose social network for posting message. 1 - Facebook 2 - Twitter 2 Checking user's parameters Name: Jhonatan Password: **** .......... LogIn success on Twitter Message: 'Hello, World!' was posted on Twitter User: 'Jhonatan' was logged out from Twitter