[Design Pattern] Template Method 템플릿메소드 패턴

이은수, Lee EunSoo·2024년 10월 5일
0

DesignPattern

목록 보기
5/12
post-thumbnail

1. 개요

템플릿 메소드 패턴은 부모-자식 계층구조를 갖는 프로그램에서 부모 클래스에서 템플릿 메소드라는 특이한 형태로 구현한 메소드를 이용하는 방식으로 추상메소드를 통해서 부모에서 정의한 함수들을 자식클래스에서 구현하지만

이 템플릿 메소드만큼은 부모클래스에서 구현한다. 이 템플릿 메소드는 해당 클래스 내부에 존재하는 추상메소드를 호출하는 형태로 구현되어 있는것이 특징이다.(부모 클래스의 객체 생성만으로는 사용이 불가능)

부모-자식의 계층구조를 가지면서 프로그램내 흐름을 지정하고자 할때 사용한다.

1.1. 의도

앞서 설명했듯 상위 클래스에서 어떤 처리흐름에 대한 골격을 정하고, 구체적인 처리의 내용은 하위클래스에서결정하기 위해서 사용한다.

1.2. 특징

  • 템플릿 메소드의 흐름을 잘보면 프로그램의 전체 흐름을 파악 할 수 있다.
  • 템플릿 메소드에서 사용되는 추상 메소드들은 하위클래스에서 구현된다.
    • 처리내용은 자식클래스에 다라 달라지지만 코드 처리 흐름은 무조건 템플릿메소드의 형태로 돌아간다.

2. 형태

사실 구조는 단순하다,상위 클래스에서 템플릿이 될 메소드만 제외하고 나머지를 하위에서 구현하도록 설계하면 된다.

2.1. 설명

Abstract Class

상위클래스를 의미하며, 여기서 템플릿 메소드를 구현한다.

나머지 메소드는 추상메소드로 만들어서 하위 클래스인 Concreate Class에서 구현하도록 만들어 준다.

Concreate Class

Abstract Class를 상속받아 추상메소드를 구현하는 클래스로 여기서 구현하는 추상메소드는 Abstract Class의 템플릿 메소드에서 호출된다.

2.2. 특징

  • 로직의 공통화
    • 핵심알고리즘이 상위클래스에 작성되어 있어 하위클래스에서 일일이 핵심 알고리즘을 구현할 필요가 없어진다.
    • 코드의 유지보수가 쉬워진다.
  • 상위클래스와 하위클래스의 연계
    • 하위클래스는 핵심기능을 동작하기 위해서 반드시 상위클래스를 상속받아 구현하는 형태가 되어야 한다.
  • 하위클래스와 상위클래스의 동일취급

3. 소스코드

다음 형태를 따르는 코드를 작성해 보겠다.

3.1. Java

public abstract class  AbstractDisplay {

	public abstract void open();
	public abstract void print();
	public abstract void close();

	public final void display() { 
		open(); //this.open()
		for (int i=0; i<5; i++) { 
			print();
		}
		close();
	}
}

public class CharDisplay extends AbstractDisplay {

	private char ch;
	public CharDisplay(char ch) { 
		this.ch = ch; 
	}

	@Override
	public void open() {
		System.out.print("<<"); 
	}

	@Override
	public void print() {
		System.out.print(ch); 
	}

	@Override
	public void close() {
		System.out.println(">>"); 
	}
}

public class StringDisplay extends AbstractDisplay {
	private String string; 
	private int width;
	public StringDisplay(String string) { 
		this.string = string; 
		this.width = string.length;
	}
	@Override
	public void open() { 
		printLine();
	}
	@Override
	public void print() { 
		System.out.println("|" + string + "|");
	}
	@Override
	public void close() { 
		printLine();
	}
    private void printLine() {
		System.out.print("+");
		
		for (int i = 0; i < width; i++) { 
			System.out.print("-"); 
		}

		System.out.println("+"); 

	}

}


public class Main {
	public static void main(String[] args) {
		
		AbstractDisplay d1 = new CharDisplay('H');
		AbstractDisplay d2 = new StringDisplay("Hello, world.");

		d1.display();
		d2.display();
	}
}

출력결과

3.2. Swift

import Foundation

// AbstractDisplay 프로토콜 정의
protocol AbstractDisplay {
    func open()
    func printContent()
    func close()
}

// 프로토콜 확장을 통해 기본 구현 제공
extension AbstractDisplay {
    func display() {
        open()
        for _ in 0..<5 {
            printContent()
        }
        close()
    }
}

// CharDisplay 클래스 정의
class CharDisplay: AbstractDisplay {
    private var ch: Character

    init(ch: Character) {
        self.ch = ch
    }

    func open() {
        print("<<", terminator: "")
    }

    func printContent() {
        print(ch, terminator: "")
    }

    func close() {
        print(">>")
    }
}

// StringDisplay 클래스 정의
class StringDisplay: AbstractDisplay {
    private var string: String
    private var width: Int

    init(string: String) {
        self.string = string
        self.width = string.count
    }

    func open() {
        printLine()
    }

    func printContent() {
        print("|" + string + "|")
    }

    func close() {
        printLine()
    }

    private func printLine() {
        print("+", terminator: "")
        for _ in 0..<width {
            print("-", terminator: "")
        }
        print("+")
    }
}

// 사용 예시
let d1: AbstractDisplay = CharDisplay(ch: "H")
let d2: AbstractDisplay = StringDisplay(string: "Hello, world.")

d1.display()
d2.display()

Swift에는 추상클래스를 제공하지 않고,
프로토콜에서 바로 함수를 기본정의 하는것을 허용하지 않으니 템플릿 메소드는 프로토콜을 extension해서 구현하였다.

4. 정리

템플릿 메소드 패턴은 코드 처리 구조를 상위 단계에서 구현하고 나머지 상세부분은 하위 클래스에서 구현하도록 설계하는 디자인 패턴이다.

profile
iOS 개발자 취준생, 천 리 길도 한 걸음부터

0개의 댓글