Template Method

Template Method ํŒจํ„ด์€ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์ „์ฒด์ ์ธ ๋ผˆ๋Œ€๋ฅผ ์ถ”์ƒ ํด๋ž˜์Šค์— ์ •์˜ํ•ด๋‘๊ณ , ๊ทธ ์ค‘ ์ผ๋ถ€ ๊ตฌ์ฒด์ ์ธ ๋‹จ๊ณ„๋Š” ์„œ๋ธŒํด๋ž˜์Šค์—์„œ ๊ตฌํ˜„ํ•˜๋„๋ก ์œ„์ž„ํ•˜๋Š” ๋””์ž์ธ ํŒจํ„ด์ž…๋‹ˆ๋‹ค.

           +-------------------------+
           |    AbstractClass        |  <-- ํ…œํ”Œ๋ฆฟ ๋ฉ”์„œ๋“œ ์ •์˜
           +-------------------------+
           | + templateMethod()      |  <-- ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์ „์ฒด ๊ตฌ์กฐ
           |   {                   } |
           |                         |
           | - primitiveOperation1() |  <-- ๊ตฌํ˜„์€ ์„œ๋ธŒํด๋ž˜์Šค์— ์œ„์ž„
           | - primitiveOperation2() |  <-- ๊ตฌํ˜„์€ ์„œ๋ธŒํด๋ž˜์Šค์— ์œ„์ž„
           +-------------------------+
                     /   \
                    /     \
                   /       \
   +----------------+   +----------------+
   | ConcreteClass1 |   | ConcreteClass2 |  <-- ๊ตฌ์ฒด์ ์ธ ๊ตฌํ˜„ ํด๋ž˜์Šค๋“ค
   +----------------+   +----------------+
   | + primitiveOperation1() ๊ตฌํ˜„  | 
   | + primitiveOperation2() ๊ตฌํ˜„  | 
   +----------------+   +----------------+

์ฆ‰, ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๊ณตํ†ต ๋ถ€๋ถ„์€ ๋ถ€๋ชจ ํด๋ž˜์Šค์—์„œ ์ฒ˜๋ฆฌํ•˜๊ณ , ๋ณ€ํ•˜๋Š” ๋ถ€๋ถ„์€ ์ž์‹ ํด๋ž˜์Šค์—์„œ ๊ตฌํ˜„ํ•˜์—ฌ ์ฝ”๋“œ์˜ ์ค‘๋ณต์„ ์ค„์ด๊ณ , ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

How do Code?

// ์ถ”์ƒ ํด๋ž˜์Šค: ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๋ผˆ๋Œ€๋ฅผ ์ •์˜ํ•˜๋Š” ํ…œํ”Œ๋ฆฟ ๋ฉ”์„œ๋“œ ํฌํ•จ
public abstract class AbstractClass {
    
    // ํ…œํ”Œ๋ฆฟ ๋ฉ”์„œ๋“œ: ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์ „์ฒด ๊ตฌ์กฐ๋ฅผ ์ •์˜ํ•˜๋ฉฐ, ์ผ๋ถ€ ๋‹จ๊ณ„๋Š” ์ถ”์ƒ ๋ฉ”์„œ๋“œ๋กœ ์œ„์ž„
    public final void templateMethod() {
        primitiveOperation1();
        primitiveOperation2();
        concreteOperation();
    }
    
    // ์„œ๋ธŒํด๋ž˜์Šค์—์„œ ๊ตฌํ˜„ํ•  ์ถ”์ƒ ๋ฉ”์„œ๋“œ๋“ค
    protected abstract void primitiveOperation1();
    protected abstract void primitiveOperation2();
    
    // ๊ณตํ†ต์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๊ตฌ์ฒด์ ์ธ ๋ฉ”์„œ๋“œ (ํ•„์š”์— ๋”ฐ๋ผ ์˜ค๋ฒ„๋ผ์ด๋”ฉ ๊ฐ€๋Šฅ)
    private void concreteOperation() {
        System.out.println("AbstractClass์˜ ๊ณตํ†ต ์ž‘์—… ์ˆ˜ํ–‰");
    }
}

// ๊ตฌ์ฒด์ ์ธ ๊ตฌํ˜„ ํด๋ž˜์Šค 1
public class ConcreteClass1 extends AbstractClass {
    @Override
    protected void primitiveOperation1() {
        System.out.println("ConcreteClass1: primitiveOperation1 ์ˆ˜ํ–‰");
    }
    
    @Override
    protected void primitiveOperation2() {
        System.out.println("ConcreteClass1: primitiveOperation2 ์ˆ˜ํ–‰");
    }
}

// ๊ตฌ์ฒด์ ์ธ ๊ตฌํ˜„ ํด๋ž˜์Šค 2
public class ConcreteClass2 extends AbstractClass {
    @Override
    protected void primitiveOperation1() {
        System.out.println("ConcreteClass2: primitiveOperation1 ์ˆ˜ํ–‰");
    }
    
    @Override
    protected void primitiveOperation2() {
        System.out.println("ConcreteClass2: primitiveOperation2 ์ˆ˜ํ–‰");
    }
}
  • ํ…œํ”Œ๋ฆฟ ๋ฉ”์„œ๋“œ(templateMethod()) ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์ „์ฒด ํ๋ฆ„์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ํ…œํ”Œ๋ฆฟ ๋ฉ”์„œ๋“œ ๋‚ด์—์„œ ๊ณตํ†ต์œผ๋กœ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•˜๋Š” ๋‹จ๊ณ„์™€, ์„œ๋ธŒํด๋ž˜์Šค์—์„œ ๊ฐ๊ฐ ๋‹ค๋ฅด๊ฒŒ ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๋Š” ์ถ”์ƒ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

  • primitiveOperation1()์™€ primitiveOperation2() ์„œ๋ธŒํด๋ž˜์Šค์—์„œ ๊ตฌ์ฒด์ ์œผ๋กœ ๊ตฌํ˜„ํ•  ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋“ค์ด ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•œ ๋ถ€๋ถ„์„ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค.

  • concreteOperation() ์•Œ๊ณ ๋ฆฌ์ฆ˜์—์„œ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๊ณ  ๊ณตํ†ต์œผ๋กœ ์ˆ˜ํ–‰๋˜๋Š” ์ž‘์—…์œผ๋กœ, ๋ณดํ†ต private ๋ฉ”์„œ๋“œ๋กœ ์ •์˜๋˜์–ด ์„œ๋ธŒํด๋ž˜์Šค์—์„œ ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

  • ์žฅ์  ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๊ณตํ†ต ๋ถ€๋ถ„๊ณผ ๋ณ€ํ™”ํ•˜๋Š” ๋ถ€๋ถ„์„ ๋ถ„๋ฆฌํ•จ์œผ๋กœ์จ ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ์„ฑ์„ ๋†’์ด๊ณ , ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๊ตฌ์กฐ๋ฅผ ์ผ์ •ํ•˜๊ฒŒ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Last updated