Design Pattern

[Design Pattern] 8. Tamplate Method Pattern(탬플릿 메소드 패턴) C#

o0zrone 2023. 3. 28. 16:48
728x90

일련의 동작을 하나로 묶고 필요한 부분만 자식 클래스에 위임하여 구현하는 패턴입니다.

 

행동 패턴(Behavioral Design Patterns)중 하나이죠.

 

장점

  • 특정 부분만 오버라이드하여 다른 부분의 변경에 영향을 덜 받도록 할 수 있습니다.
  • 중복 코드를 부모 클래스에 모을 수 있습니다.

단점

  • 부모 클래스에 제공된 탬플릿에 의해 일부 구현이 제한될 수 있습니다.
  • 자식 클래스를 통해 디폴트 단계 구현을 억제하여 리스코프 치환 원칙을 위반할 수 있습니다.
  • 템플릿 메서드들은 단계들이 많아질수록 유지가 더 어려워집니다.

 

C#으로 Console 프로젝트를 하나 생성해서 할 것입니다.

 

목표는 Main에서 라는 변수를 통한 다양한 연산 결과를 출력입니다.

 

프로젝트의 tree구조는 아래와 같습니다.

Template (Project)

|- Program.cs (Main)

|- MakeTeaBase.cs (Template abstract)

|- GreenTea.cs (Concreate Class)

|- RedTea.cs (Concreate Class)

|- User.cs (Client)

 

MakeTeaBase.cs

using System;

namespace template
{
    public abstract class MakeTeaBaseClass
    {
        public void MakeTea()
        {
            PrepareCup();
            FillTea();
            BoilWater();
            PourOverTea();
        }

        public void PrepareCup()
        {
            Console.WriteLine("Prepare Tea Cup");
        }

        public virtual void FillTea()
        {
            Console.WriteLine("i dont want tea");
        }

        public void BoilWater()
        {
            Console.WriteLine("Boil fresh and cold water");
        }

        public abstract void PourOverTea();
    }
}

MakeTea라는 Template Method를 만들어줍니다.

abstract이 붙은 메소드는 자식 클래스에서 구현할 클래스로 구현을 강제했습니다.

virtual이 붙은 FillTea 메소드는 비어있지만 자식 클래스에서 구현할 수도 있는 메소드로 Hook Method라고 부릅니다.

 

GreenTea.cs

using System;

namespace template
{
    public class GreenTea : MakeTeaBaseClass
    {
        public override void FillTea()
        {
            Console.WriteLine("Fill Green Tea leaves");
        }

        public override void PourOverTea()
        {
            Console.WriteLine("Pour in 80 degree water and wait 3 minutes");
        }
    }
}

abstract와 virtual 메소드를 override를 해줍니다.

 

RedTea.cs

using System;

namespace template
{
    public class RedTea : MakeTeaBaseClass
    {
        public override void FillTea()
        {
            Console.WriteLine("Fill Red Tea leaves");
        }

        public override void PourOverTea()
        {
            Console.WriteLine("Pour in 100 degree water and wait 5 minutes");
        }
    }
}

GreenTea와 동일하게 abstract와 virtual 메소드를 override를 해줍니다.

 

User.cs

namespace template
{
    public class User
    {
        public static void MakeTea(MakeTeaBaseClass makeTea)
        {
            makeTea.MakeTea();
        }
    }
}

User라는 Make Tea를 해주는 클래스를 만들어줍니다.

 

Program.cs

using System;

namespace template
{
    class Program
    {
        static void Main(string[] args)
        {
            User.MakeTea(new GreenTea());
            Console.WriteLine();
            User.MakeTea(new RedTea());
        }
    }
}

먼저 GreenTea를 만들고 다음에 RedTea를 만들게 구성해주면 아래와 같이 출력됩니다.

 

실행 결과

동일한 알고리즘에서 일부 특정 부분만 바뀌는 경우가 아니라면 그렇게 다양하게 적용되지 않는거 같습니다.