
자바로 작성된 템플릿 메서드
템플릿 메서드는 기초 클래스에서 알고리즘의 골격을 정의할 수 있도록 하는 행동 디자인 패턴입니다. 또 이 패턴은 자식 클래스들이 전체 알고리즘의 구조를 변경하지 않고도 기본 알고리즘의 단계들을 오버라이드할 수 있도록 합니다.
복잡도:
인기도:
사용 사례들: 템플릿 메서드 패턴은 자바 프레임워크들에서 매우 일반적이며 개발자들은 종종 이 패턴을 사용하여 프레임워크 사용자들에게 상속을 사용하여 표준 기능들을 확장하는 간단한 수단을 제공합니다.
다음은 코어 자바 라이브러리로부터 가져온 템플릿 메서드의 몇 가지 예시들입니다:
-
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
](http://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpServlet.html) 클래스에서 모든 doXXX() 메서드들은 HTTP 405 '메서드 허용되지 않음' 에러를 기본값 응답으로 보냅니다. 그러나 당신은 이러한 모든 메서드들 오버라이딩하여 다른 에러 메시지를 응답으로 보내게 할 수 있습니다.
식별: 템플릿 메서드는 기초 클래스에 추상적이거나 비어 있는 다른 여러 메서드들을 호출하는 메서드가 있습니다.
알고리즘의 표준 단계들의 오버라이드
이 예시에서 템플릿 메서드 패턴은 소셜 네트워크와 작업하는 알고리즘을 정의합니다. 특정 소셜 네트워크에 해당하는 자식 클래스들은 이러한 단계들을 소셜 네트워크에서 제공하는 API에 따라 구현합니다.
networks
networks/Network.java: 기초 소셜 네트워크 클래스
package refactoring_guru.template_method.example.networks; /** * Base class of social network. */ public abstract class Network { String userName; String password; Network() {} /** * Publish the data to whatever network. */ public boolean post(String message) { // Authenticate before posting. Every network uses a different // authentication method. if (logIn(this.userName, this.password)) { // Send the post data. 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; /** * Class of social network */ 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; /** * Class of social network */ 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; /** * Demo class. Everything comes together here. */ 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(); // Enter the message. 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()); // Create proper network object and send the message. 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