템플릿 방법과 전략 패턴의 차이점은 무엇입니까?


161

누군가 템플릿 방법 패턴과 전략 패턴의 차이점이 무엇인지 설명해 주시겠습니까?

내가 알 수있는 한 99 % 동일하다는 점은 템플릿 메서드 패턴에 기본 클래스와 같은 추상 클래스가 있고 전략 클래스는 각 구체적인 전략 클래스에 의해 구현되는 인터페이스를 사용한다는 것입니다.

그러나 고객 에 관한 한 정확히 동일한 방식으로 소비됩니다. 이것이 맞습니까?


2
SO의이 게시물은 같은 질문에 대한 더 나은 답변을 제공합니다. stackoverflow.com/questions/464524/…
Gob00st

12
gob00st와 관련된 질문은 전략과 다리의 차이입니다. 이 질문에 대한 답이 아닙니다.
bluekeys

답변:


135

이 둘의 주요 차이점은 구체적 알고리즘을 선택할 때입니다.

Template 메소드 패턴을 사용하면 템플리트서브 클래 싱 하여 컴파일 타임 에 발생 합니다. 각 서브 클래스는 템플릿의 추상 메소드를 구현하여 다른 구체적인 알고리즘을 제공합니다. 클라이언트가 템플릿의 외부 인터페이스 메서드를 호출하면 템플릿을 호출하여 알고리즘을 호출하는 데 필요한 추상 메서드 (내부 인터페이스)를 호출합니다.

class ConcreteAlgorithm : AbstractTemplate
{
    void DoAlgorithm(int datum) {...}
}

class AbstractTemplate
{
    void run(int datum) { DoAlgorithm(datum); }

    virtual void DoAlgorithm() = 0; // abstract
}

대조적으로, 전략 패턴은 알고리즘에이 선택 될 수 있도록 실행 에 의해 봉쇄 . 구체적인 알고리즘은 생성자 또는 setter 메서드에 매개 변수로 전략에 전달되는 별도의 클래스 또는 함수로 구현됩니다. 이 매개 변수에 대해 선택된 알고리즘은 프로그램의 상태 또는 입력에 따라 동적으로 달라질 수 있습니다.

class ConcreteAlgorithm : IAlgorithm
{
    void DoAlgorithm(int datum) {...}
}

class Strategy
{
    Strategy(IAlgorithm algo) {...}

    void run(int datum) { this->algo.DoAlgorithm(datum); }
}

요약해서 말하자면:

  • 템플릿 메소드 패턴 : 서브 클래 싱에 의한 컴파일 타임 알고리즘 선택
  • 전략 패턴 : 격리에 의한 런타임 알고리즘 선택

47
두 패턴 모두 사용 된 알고리즘의 런타임 선택을 지원하므로 (템플릿 방법의 경우와 같은 작업을 수행함 if (config.useAlgoA) impl = new AlgoA() else impl = new AlgoB())이 답변이 잘못되었습니다.
Borek Bernard

13
물론 그렇게 할 수는 있지만 템플릿 패턴을 사용하지 않습니다. 실제로, Strategy 인스턴스를 생성하는 코드는 거의 정확히 이와 같습니다!
thehouse

21
-1, 나는이 대답 (완전히 틀린 것은 아니지만)이 실제 차이가있는 지점을 놓친다고 생각합니다. @tvanfosson의 대답이 훨씬 좋습니다.
Doc Brown

1
@Karoly Nyisztor 둘 다 "동작을 대체하고"확장 점을 제공 할 수 있습니다. 행동이나 확장에 관계없이 주어진 패턴을 적용하는 위치에 달려 있습니다. 템플릿 메소드 패턴의 각 서브 클래스를 "전략"이라고 부르거나 전략 패턴의 각 전략 클래스를 "확장"이라고 부를 수 있습니다. 문제의 사실은 그들이이 답변에서 언급 한 차이점을 제외하고 똑같은 일을한다는 것입니다. 이것이 정답입니다.
Andy

1
구체적인 알고리즘은 두 패턴 모두에 대해 동일한 방식으로 선택됩니다. new ConcreteAlgorithm1()vs 를 호출 하여 선택 new ConcreteAlgorithm2()합니다. 분명히 선택은 런타임에 발생합니다 (컴파일 타임에 알고리즘을 선택하면 하드 코딩을 의미합니다). 이 둘의 주요 차이점은 구체적인 알고리즘이 구현되는 방식입니다. 서브 클래스 또는 별도의 인터페이스로 구현됩니까? 전자는 템플릿입니다. 후자는 전략이다. 그 차이점은 GoF 책의 공통 주제 인 구성 대 상속으로 요약 될 수 있습니다.
jaco0646

138

템플릿 패턴은 특정 작업에 다른 다양한 기본 동작과 관련하여 정의 할 수있는 일정하지 않은 동작이있을 때 사용됩니다. 추상 클래스는 불변 동작을 정의하고 구현 클래스는 종속 메소드를 정의합니다.

전략에서 행동 구현은 독립적입니다. 각 구현 클래스는 행동을 정의하며 그들 사이에 코드가 공유되지 않습니다. 둘 다 행동 패턴이며, 따라서 클라이언트는 거의 같은 방식으로 소비합니다. 일반적으로 전략에는 단일 공용 메소드 ( execute()메서드)가 있지만, 템플리트는 서브 클래스가 구현해야하는 지원 개인용 기본 세트뿐만 아니라 공개 메소드 세트를 정의 할 수 있습니다.

두 패턴을 쉽게 함께 사용할 수 있습니다. 템플릿 패턴을 사용하여 구현 된 전략 군에 여러 구현이 속하는 전략 패턴이있을 수 있습니다.


WikiPedia 가 왜 "런타임에 알고리즘의 동작을 선택하는 전략 패턴" 이라고 언급 하는가? 템플릿 방법과 마찬가지로 컴파일 타임에 알고리즘의 동작을 선택하는 데에도 사용할 수 있습니까? 뭔가 빠졌습니까?
BornToCode

2
@BornToCode 나는 그들이 말하는 것이 런타임에 특정 전략을 선택하는 것이라고 가정합니다. 예를 들어, 방정식의 근을 수치 적으로 찾는 몇 가지 방법이 있습니다. 문제 영역이나 데이터에 따라 Newton-Raphson, Euler 또는 방정식 해결을위한 다른 전략을 선택할 수 있습니다. 이들 각각은 전략입니다. 방정식을 푸는 큰 알고리즘은 문제의 품질에 따라 채택 할 전략을 선택합니다.
tvanfosson

예,하지만 전략 패턴이 그러한 경우에만 사용해야하는 것과는 다른가요? 컴파일 타임에 알고리즘의 동작 만 선택해야하는 경우에도 전략 패턴을 사용해야합니까, 아니면 그렇게 사용하지 않아야합니까?
BornToCode

1
@BornToCode 나는 선택이 역동적 일 때 전략이 가장 유용하다고 말하고 싶다. 템플릿은 기본적으로 알려진 다른 관련 동작을 작성하는 방법입니다. 어떤 템플릿 동작을 채택할지 선택하기 위해 전략 (전략 패턴은 아니지만)을 사용합니다. 예를 들어 제품 상속-기본 제품을 만들고 다른 제품에 대한 기능을 추가합니다. 인스턴스화 할 제품 유형 (클래스)을 선택하는 것은로드 된 테이블 / 뷰에 따라 다릅니다. 전략 패턴은 실제로 적용되지 않습니다.
tvanfosson

2
@BornToCode 그것은 / 또는 일이 아닙니다. 그렇습니다. 적절한 곳에 패턴을 적용하고 유용한 곳에 패턴을 결합하십시오.
tvanfosson


24

아마도 템플릿 메소드 패턴을 의미 할 것입니다. 당신은 옳습니다, 그들은 매우 비슷한 요구를 제공합니다. 서브 클래스가 이러한 단계를 재정 의하여 세부 사항을 변경하는 단계를 정의한 "템플릿"알고리즘이있는 경우 템플리트 메소드를 사용하는 것이 좋습니다. 전략의 경우 인터페이스를 작성해야하며 상속 대신 위임을 사용하고 있습니다. 나는 그것이 좀 더 강력한 패턴이라고 말하고 DIP 의존성 역전 원칙에 따라 더 좋을 것이라고 말했다. 템플릿 방법에는 적용되지 않는 무언가를 수행하는 방법 인 새로운 전략 추상화를 명확하게 정의하기 때문에 더욱 강력합니다. 따라서이 추상화가 의미가 있다면 사용하십시오. 그러나 템플릿 방법을 사용하면 간단한 경우에 더 단순한 디자인을 제공 할 수도 있습니다. 어떤 단어가 더 잘 맞는지 고려하십시오. 템플릿 알고리즘이 있습니까? 아니면 전략의 추상화를 가지고 있다는 것이 핵심입니다.

템플릿 방법의 예 :

Application.main()
{
Init();
Run();
Done();
}

여기에서 응용 프로그램에서 상속하고 init, run 및 done에서 수행 할 작업을 정확하게 대체합니다.

전략의 예 :

array.sort (IComparer<T> comparer)

여기서 비교자를 작성할 때 배열에서 상속하지 않습니다. 배열은 비교 알고리즘을 비교 자에게 위임합니다.


3
나는 이것이 훌륭한 답변이라고 생각합니다
Calanus

23

전략과 템플릿 방법의 차이점 패턴 전략과 템플릿 방법


유사점

전략과 템플릿 방법 패턴은 서로 유사합니다. 전략 및 템플릿 방법 패턴은 모두 공개 원칙을 충족하고 코드를 변경하지 않고도 소프트웨어 모듈을 쉽게 확장 할 수 있도록하는 데 사용할 수 있습니다. 두 패턴 모두 해당 기능의 세부 구현에서 일반 기능이 분리 된 것을 나타냅니다. 그러나 제공하는 세분성 측면에서 약간 다릅니다.


차이점

다음은이 두 가지 패턴을 연구 할 때 관찰 한 몇 가지 차이점입니다.

  1. 전략에서는 클라이언트와 전략의 연결이 느슨하지만 템플릿 방법에서는 두 모듈이 더 밀접하게 연결됩니다.
  2. Strategy에서는 상황에 따라 abstract 클래스를 사용할 수 있지만 대부분 인터페이스가 사용되며 구체적 클래스는 사용되지 않지만 Template 메서드에서는 주로 abstract 클래스 또는 concrete 클래스가 사용되며 인터페이스는 사용되지 않습니다.
  3. 전략 패턴에서 일반적으로 클래스의 전체 동작은 인터페이스 측면에서 표현되지만, 템플릿 방법은 코드 중복을 줄이기 위해 사용되며 상용구 코드는 기본 프레임 워크 또는 추상 클래스로 정의됩니다. 템플릿 메소드에는 기본 구현으로 구체적인 클래스가있을 수도 있습니다.
  4. 간단히 말하면 전략 패턴에서 전체 전략 (알고리즘)을 변경할 수 있지만 템플릿 방법에서는 일부 내용 만 변경되고 (알고리즘의 일부) 나머지 내용은 변경되지 않습니다. 템플릿 방법에서 변하지 않는 단계는 추상 기본 클래스로 구현되는 반면 변형 단계에는 기본 구현이 제공되거나 전혀 구현되지 않습니다. 템플릿 방법에서 구성 요소 디자이너는 알고리즘의 필수 단계와 단계 순서를 지시하지만 구성 요소 클라이언트는 이러한 단계 중 일부를 확장하거나 대체 할 수 있습니다.

물린 블로그 에서 이미지를 가져옵니다 .


19

상속 대 집계 (is-a vs has-a). 동일한 목표를 달성하는 두 가지 방법이 있습니다.

이 질문은 선택 사이의 일부 상충 관계를 보여줍니다. 상속과 집계


11

둘 다 매우 유사하며 클라이언트 코드가 비슷한 방식으로 소비합니다. 위의 가장 인기있는 답변과 달리 둘 다 런타임에 알고리즘을 선택할 수 있습니다 .

이 둘의 차이점은 전략 패턴이 다른 구현에서 원하는 결과를 달성하기 위해 완전히 다른 방식을 사용할 수 있지만 템플릿 방법 패턴 은 결과를 달성하는 데 사용되는 포괄적 인 알고리즘 ( "템플릿"방법)을 지정한다는 것입니다. -특정 구현 (서브 클래스)에 남겨진 유일한 선택은 상기 템플릿 방법의 특정 세부 사항이다. 이것은 템플리트 메소드가 자체적으로 서브 클래스에 의해 오버라이드되지 않은 템플리트 메소드와 달리 서브 클래스에 의해 대체되는 (즉, 구현 된) 하나 이상의 추상 메소드를 호출하게함으로써 수행됩니다. .

클라이언트 코드는 전략 패턴을 사용하는 것처럼 런타임에 결정될 수있는 구체적인 하위 클래스 중 하나의 인스턴스를 가리키는 추상 클래스 유형의 참조 / 포인터를 사용하여 템플리트 메소드를 호출합니다.


9

템플릿 방법 :

  1. 상속을 기반으로합니다.
  2. 서브 클래스로 변경할 수없는 알고리즘의 골격을 정의합니다. 하위 클래스에서는 특정 작업 만 재정의 할 수 있습니다.
  3. 부모 클래스 는 알고리즘을 완전히 제어하며 구체적인 단계와 구체적인 단계 만 다릅니다.
  4. 컴파일 타임에 바인딩이 수행됩니다.

Template_method 구조 :

여기에 이미지 설명을 입력하십시오

전략:

  1. 위임 / 구성을 기반으로합니다.
  2. 메소드 동작을 수정 하여 오브젝트의 내장을 변경합니다.
  3. 알고리즘 계열간에 전환 하는 데 사용됩니다.
  4. 런타임시 한 알고리즘을 다른 알고리즘 으로 완전히 대체하여 런타임시 오브젝트의 동작을 변경합니다.
  5. 바인딩은 런타임에 수행됩니다.

전략 구조 :

여기에 이미지 설명을 입력하십시오

더 나은 이해를 위해 템플릿 방법전략 기사를 살펴보십시오 .

관련 게시물:

JDK의 템플리트 디자인 패턴이 순서대로 실행될 메소드 세트를 정의하는 메소드를 찾을 수 없습니다.

전략 패턴의 실제 예


3

아니요, 반드시 같은 방식으로 소비되는 것은 아닙니다. "템플릿 방법"패턴은 미래 구현 자에게 "지침"을 제공하는 방법입니다. 당신은 그들에게 "모든 개인 개체는 사회 보장 번호를 가지고 있어야합니다"라고 말하고 있습니다. (사소한 예이지만 아이디어를 올바르게 전달합니다).

전략 패턴을 통해 여러 가능한 구현을 켜고 끌 수 있습니다. 상속을 통해 (보통) 구현되는 것이 아니라 호출자가 원하는 구현을 통과하도록하여 구현됩니다. 예를 들어 ShippingCalculator에 세금을 계산하는 여러 가지 방법 중 하나 (NoSalesTax 구현 및 아마도 PercentageBasedSalesTax 구현)가 제공 될 수 있습니다.

따라서 때로는 클라이언트 가 실제로 사용할 전략을 객체에 알려줍니다. 에서와 같이

myShippingCalculator.CalculateTaxes(myCaliforniaSalesTaxImpl);

그러나 클라이언트는 템플릿 방법을 기반으로 한 객체에 대해서는 그렇게하지 않을 것입니다. 실제로 클라이언트는 템플릿 방법에 기반한 객체를 알지 못할 수도 있습니다. 템플릿 메소드 패턴의 추상 메소드는 보호 될 수도 있으며,이 경우 클라이언트는 자신이 존재하는지도 알지 못할 것입니다.


3

기사 를 읽으라고 제안합니다 . 실제 사례의 차이점을 설명합니다.

기사에서 인용

" 클래스 구현은 템플릿 메소드 클래스에 따라 달라집니다.이 종속성은 알고리즘의 일부 단계를 변경하려는 경우 템플리트 메소드를 변경합니다. 다른 쪽 전략에서는 알고리즘을 완전히 캡슐화합니다. 알고리즘을 완전히 정의하는 클래스이므로 변경 사항이 도착하면 이전에 작성된 클래스의 코드를 변경해야하므로 클래스 디자인 전략을 선택하는 주된 이유입니다.

템플릿 방법의 한 가지 특징은 템플릿 방법이 알고리즘을 제어한다는 것입니다. 다른 상황에서 좋은 일이 될 수 있지만 내 문제로 인해 클래스 디자인이 제한되었습니다. 반면에 전략은 완전히 다른 변환 방법을 추가 할 수있는 알고리즘 단계를 제어하지 않습니다. 따라서 필자의 경우 전략은 구현에 도움이됩니다.

전략의 한 가지 단점은 코드 중복이 너무 많고 코드 공유가 적다는 것입니다. 이 기사의 제시된 예에서 알 수 있듯이 동일한 코드를 4 개의 클래스에서 반복해서 반복해야합니다. 따라서 모두에게 공통적 인 4 단계와 같은 시스템의 구현이 변경되면 5 개 클래스 모두에서이를 업데이트해야하기 때문에 유지 관리하기가 어렵습니다. 반면 템플릿 방법에서는 수퍼 클래스 만 변경할 수 있으며 변경 사항은 하위 클래스에 반영됩니다. 따라서 템플릿 메서드는 클래스간에 매우 적은 양의 중복성과 많은 양의 코드 공유를 제공합니다.

전략은 또한 런타임에 알고리즘을 변경할 수 있습니다. 템플릿 방법에서 객체를 다시 초기화해야합니다. 이 전략 기능은 많은 유연성을 제공합니다. 디자인 관점에서 상속보다 구성을 선호해야합니다. 따라서 전략 패턴을 사용하는 것도 개발의 주요 선택이되었습니다. "


2

템플릿 패턴은 전략 패턴과 유사합니다. 이 두 패턴은 범위와 방법이 다릅니다.

전략은 발신자가 다양한 세금 유형을 계산하는 방법과 같이 전체 알고리즘을 다양하게하는 데 사용되는 반면 템플릿 방법은 알고리즘의 단계를 다양하게하는 데 사용됩니다. 이 때문에 전략은 더 거칠게 결정됩니다. 템플릿을 사용하면 후속 작업에서 세밀한 제어가 가능하지만 이러한 세부 사항의 구현은 다양 할 수 있습니다.

다른 주요 차이점은 전략은 위임을 사용하고 템플릿 방법은 상속을 사용한다는 것입니다. 전략에서 알고리즘은 주제가 참조 할 다른 xxxStrategy 클래스에 위임되지만 템플릿을 사용하면 기본을 서브 클래 싱하고 메소드를 재정 의하여 변경합니다.

에서 http://cyruscrypt.blogspot.com/2005/07/template-vs-strategy-patterns.html


2

전략 패턴에서 서브 클래스는 쇼를 실행하고 알고리즘을 제어합니다. 여기서 코드는 서브 클래스에 걸쳐 복제됩니다. 알고리즘에 대한 지식과 구현 방법은 여러 클래스에 분산되어 있습니다.

템플릿 패턴에서 기본 클래스에는 알고리즘이 있습니다. 서브 클래스 간의 재사용을 최대화합니다. 알고리즘은 한 곳에 있기 때문에 기본 클래스가이를 보호합니다.


2

전략 디자인 패턴

  • 구성을 지원합니다.
  • 런타임시 객체의 동작을 변경할 수있는 유연성을 제공합니다.
  • 클라이언트 코드와 솔루션 / 알고리즘 코드 사이의 연결이 적습니다.

템플릿 방법 디자인 패턴

  • 구성보다 상속을 선호
  • 기본 클래스에서 알고리즘을 정의하십시오. 자식 클래스에서 개별 알고리즘 조각을 사용자 지정할 수 있습니다.

1

템플릿 패턴 :

템플릿 방법은 기본 클래스에 정의 된 기본 구조와 알고리즘 단계를 변경하지 않고 서브 클래스가 알고리즘의 특정 단계를 재정의하는 것입니다. 템플릿 패턴은 일반적으로 상속을 사용하므로 기본 클래스에서 알고리즘의 일반적인 구현을 제공 할 수 있으며 필요한 경우 하위 클래스가 재정의하도록 선택할 수 있습니다.

public abstract class RobotTemplate {
    /* This method can be overridden by a subclass if required */
    public void start() {
        System.out.println("Starting....");
    }

    /* This method can be overridden by a subclass if required */
    public void getParts() {
        System.out.println("Getting parts....");
    }

    /* This method can be overridden by a subclass if required */
    public void assemble() {
        System.out.println("Assembling....");
    }

    /* This method can be overridden by a subclass if required */
    public void test() {
        System.out.println("Testing....");
    }

    /* This method can be overridden by a subclass if required */
    public void stop() {
        System.out.println("Stopping....");
    }

    /*
     * Template algorithm method made up of multiple steps, whose structure and
     * order of steps will not be changed by subclasses.
     */
    public final void go() {
        start();
        getParts();
        assemble();
        test();
        stop();
    }
}


/* Concrete subclass overrides template step methods as required for its use */
public class CookieRobot extends RobotTemplate {
    private String name;

    public CookieRobot(String n) {
        name = n;
    }

    @Override
    public void getParts() {
        System.out.println("Getting a flour and sugar....");
    }

    @Override
    public void assemble() {
        System.out.println("Baking a cookie....");
    }

    @Override
    public void test() {
        System.out.println("Crunching a cookie....");
    }

    public String getName() {
        return name;
    }
}

위 코드에서 go () 알고리즘 단계는 항상 동일하지만 서브 클래스는 특정 단계를 수행하기위한 다른 레시피를 정의 할 수 있습니다.

전략 패턴 :

전략 패턴은 클라이언트가 런타임에 구체적인 알고리즘 구현을 선택하도록하는 것입니다. 모든 알고리즘은 독립적이며 독립적이지만 공통 인터페이스를 구현하며 알고리즘 내에서 특정 단계를 정의한다는 개념은 없습니다.

/**
 * This Strategy interface is implemented by all concrete objects representing an
 * algorithm(strategy), which lets us define a family of algorithms.
 */
public interface Logging {
    void write(String message);
}

/**
 * Concrete strategy class representing a particular algorithm.
 */
public class ConsoleLogging implements Logging {

    @Override
    public void write(String message) {
        System.out.println(message); 
    }

}

/**
 * Concrete strategy class representing a particular algorithm.
 */
public class FileLogging implements Logging {

    private final File toWrite;

    public FileLogging(final File toWrite) {
        this.toWrite = toWrite;
    }

    @Override
    public void write(String message) {
        try {
            final FileWriter fos = new FileWriter(toWrite);
            fos.write(message);
            fos.close();
        } catch (IOException e) {
            System.out.println(e);
        }
    }

}

전체 소스 코드는 github repository를 확인하십시오 .


0

전략은 추상 클래스로서 인터페이스 및 템플릿 방법으로 노출됩니다. 이것은 일반적으로 프레임 워크에서 많이 사용됩니다. 예를 들어 Spring 프레임 워크의 MessageSource 클래스는 메시지를 해결하기위한 전략 인터페이스입니다. 클라이언트는이 인터페이스의 특정 구현 (전략)을 사용합니다.

동일한 메시지 AbstractMessageSource의 추상 구현은 메시지 해결을 공통으로 구현하고 resolveCode () 추상 메소드를 노출시켜 서브 클래스가 해당 방식으로 구현할 수 있도록합니다. AbstractMessageSource는 템플릿 메소드의 예입니다.

http://docs.spring.io/spring/docs/4.1.7.RELEASE/javadoc-api/org/springframework/context/support/AbstractMessageSource.html


0

이 디자인 패턴의 템플릿 방법에서, 서브 클래스에 의해 하나 이상의 알고리즘 단계가 재정의되어 다른 동작을 허용하면서도 중요한 알고리즘이 계속 준수되도록 할 수 있습니다 (위키).

패턴 이름 템플릿 방법은 그것이 무엇인지 의미합니다. CalculateSomething () 메소드가 있고이 메소드를 템플리트 화하려고한다고 가정하십시오. 이 메소드는 기본 클래스에서 비가 상 메소드로 선언됩니다. 방법이 다음과 같다고 가정하십시오.

CalculateSomething(){
    int i = 0;
    i = Step1(i);
    i++;
    if (i> 10) i = 5;
    i = Step2(i);
    return i;

} Step1 및 Step2 메소드 구현은 파생 클래스에 의해 제공 될 수 있습니다.

전략 패턴에는 기본에서 제공하는 구현이 없습니다 (이것이 기본이 실제로 클래스 다이어그램의 인터페이스 인 이유입니다)

전형적인 예는 정렬입니다. 객체 수를 기준으로 정렬해야하는 적절한 알고리즘 클래스 (병합, 버블, 빠른 등)가 생성되고 전체 알고리즘이 각 클래스에 캡슐화됩니다.

이제 정렬을 템플릿 메소드로 구현할 수 있습니까? 확실히 당신은 할 수 있지만, 기본 구현에서 추상화되고 배치 될 공통점은 많지 않을 것입니다. 따라서 템플릿 메소드 패턴의 목적을 무시합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.