디자인 패턴 공부회 제3회:Template Method 패턴

소개



본 엔트리는 모사내에서 실시하는 디자인 패턴 공부회용의 자료가 됩니다.
본 엔트리로 서적 「 Java 언어로 배우는 디자인 패턴 입문 」를 베이스로 학습을 진행합니다만, 샘플 코드는 C#에 옮겨놓고 해설합니다.

제1회: Iterator 패턴
제2회: 어댑터 패턴

Template Method 패턴이란?



Templete Method란, 슈퍼 클래스로 처리의 큰 프레임이 되는 것을 결정해, 서브 클래스 중에서 구체적인 내용을 결정하는 디자인 패턴입니다.

샘플 클래스 다이어그램





각 클래스의 역할




이름    
역할


AbstractDisplay
메서드 Display만 구현되는 추상 클래스

CharDisplay
메서드 Open,Print,Close를 구현하는 클래스

StringDisplay
메서드 Open,Print,Close를 구현하는 클래스

Main
동작 테스트용 클래스



AbstractDisplay 클래스



AbstractDisplay 클래스에서는 Open, Print, Close의 추상 메소드와 Display가 구현되고 있다.
  • Display 메소드에서는, Print 메소드를 5회 호출하는 처리가 쓰여져 있다
  •     public abstract class AbstractDisplay
        {
            public abstract void Open();
            public abstract void Print();
            public abstract void Close();
    
            public void Display()
            {
                Open();
                for(int i = 0; i < 5; i++)
                {
                    Print();
                }
                Close();
            }
        }
    

    CharDisplay 클래스



    CharDisplay 클래스는 서브 클래스이며, 이하의 메소드가 구현되고 있다.
  • 메소드 처리



  • 메소드 이름  
    처리


    Open
    문자열 "<<"표시

    인쇄
    생성자에서 주어진 한 문자를 표시합니다.

    Close
    문자열 ">>"표시

    public class CharDisplay : AbstractDisplay
    {
        private char ch { get; set; }
    
        public CharDisplay(char ch)
        {
            this.ch = ch;
        }
    
        public override void Open()
        {
            Console.Write("<<");
        }
    
        public override void Print()
        {
            Console.Write(ch);
        }
    
        public override void Close()
        {
            Console.WriteLine(">>");
        }
    }
    

    StringDisplay 클래스



    CharDisplay 클래스와 같이 이쪽의 클래스도 서브 클래스가 되고 있다.
    다음의 메소드를 구현하고 있다.
  • 메소드 처리



  • 메소드 이름  
    처리


    Open
    문자열 "+------+"표시

    인쇄
    생성자에 의해 주어진 문자열을 ""와 ""사이에 끼워 표시

    Close
    문자열 "+------+"표시

    public class StringDisplay : AbstractDisplay
    {
        private string stringView { set; get; }
        private int width { set; get; }
    
        public StringDisplay(string stringView)
        {
            this.stringView = stringView;
            int stringViewLength = System.Text.Encoding.GetEncoding(932).GetByteCount(stringView);
            this.width = stringViewLength;
        }
    
        public override void Open()
        {
            PrintLine();
        }
    
        public override void Print()
        {
            Console.WriteLine("|" + stringView + "|");
        }
    
        public override void Close()
        {
            PrintLine();
        }
    
        private void PrintLine()
        {
            Console.Write("+");
            for(int i = 0; i < width; i++)
            {
                Console.Write("+");
            }
    
            Console.WriteLine("+");
        }
    }
    

    Main 클래스



    Main 클래스는 동작 테스트를 실시하는 것이 된다. 지금까지 만든 클래스의 인스턴스를 생성해, Display 메소드를 호출하고 있다.
    이번에는 Main 클래스라는 이름이 아니라 Start라는 클래스 이름으로 구현했다.
    class Start
    {
        static void Main(string[] args)
        {
            AbstractDisplay charDisplay = new CharDisplay('H');
            AbstractDisplay stringDisplayOnce = new StringDisplay("こんにちは");
            AbstractDisplay stringDisplayTwice = new StringDisplay("こんばんわ");
    
            charDisplay.display();
            stringDisplayOnce.display();
            stringDisplayTwice.display();
    
            Console.ReadLine();
        }
    }
    

    Console.ReadLine을 넣으면 버튼을 누를 때까지 콘솔을 볼 수 있도록 변경했습니다.

    실행 결과



    실행하면 다음과 같이 된다.
    <<HHHHH>>
    ++++++++++++
    |こんにちは|
    |こんにちは|
    |こんにちは|
    |こんにちは|
    |こんにちは|
    ++++++++++++
    ++++++++++++
    |こんばんわ|
    |こんばんわ|
    |こんばんわ|
    |こんばんわ|
    |こんばんわ|
    ++++++++++++
    

    Template Method의 장점



    이 디자인 패턴을 사용하는 이점은 다음과 같습니다.
  • 수퍼 클래스 측에서 알고리즘을 설명하기 때문에 서브 클래스에서 알고리즘을 작성할 필요가 없습니다
  • 슈퍼 클래스에서 실수를 발견하면 그것을 고치면 다른 수정이 필요하지 않습니다
  • 서브 클래스를 슈퍼 클래스와 동일시하고있다


  • 샘플 코드



    아래에 공개하고 있습니다.

    좋은 웹페이지 즐겨찾기