IT박스

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

itboxs 2020. 6. 6. 08:57
반응형

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


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

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

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


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

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); }
}

요약하자면:

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

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

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

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


두 패턴의 클래스 다이어그램이 차이점을 보이고 있다고 생각합니다.

전략
클래스 내부의 알고리즘을 캡슐화합니다.
이미지에 연결 여기에 이미지 설명을 입력하십시오

템플릿 메소드
연기 서브 클래스에 대한 알고리즘의 정확한 단계
이미지 링크 여기에 이미지 설명을 입력하십시오


You probably mean template method pattern. You are right, they serve very similar needs. I would say it is better to use template method in cases when you have a "template" algorithm having defined steps where subclasses override these steps to change some details. In case of strategy, you need to create an interface, and instead of inheritance you are using delegation. I would say it is a bit more powerful pattern and maybe better in accordance to DIP - dependency inversion principles. It is more powerful because you clearly define a new abstraction of strategy - a way of doing something, which does not apply to template method. So, if this abstraction makes sense - use it. However, using template method may give you simpler designs in simple cases, which is also important. Consider which words fit better: do you have a template algorithm? Or is the key thing here that you have an abstraction of strategy - new way of doing something

템플릿 방법의 예 :

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

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

전략의 예 :

array.sort (IComparer<T> comparer)

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


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


유사점

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


차이점

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

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

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


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

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


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

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

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


템플릿 방법 :

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

Template_method 구조 :

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

전략:

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

전략 구조 :

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

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

관련 게시물:

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

전략 패턴의 실제 예


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

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

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

myShippingCalculator.CalculateTaxes(myCaliforniaSalesTaxImpl);

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


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

기사에서 인용

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

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

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

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


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

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

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

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


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

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


전략 디자인 패턴

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

템플릿 방법 디자인 패턴

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

템플릿 패턴 :

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

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 () 알고리즘 단계는 항상 동일하지만 서브 클래스는 특정 단계를 수행하기위한 다른 레시피를 정의 할 수 있습니다.

전략 패턴 :

Strategy pattern is about letting client selects concrete algorithms implementation at runtime. All algorithms are isolated and independent, but implement a common interface, and there is no notion of defining particular steps within the algorithm.

/**
 * 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);
        }
    }

}

For full source code, check out my github repository.


Strategy is exposed as an Interface and template method as the Abstract Class. This is typically used a lot in frameworks. e.g. Spring framework's MessageSource class is a strategy interface for resolving messages. Client uses particular implementation (strategy) of this interface.

And the abstract implementation of the same interface AbstractMessageSource, which has common implementation of resolving messages and exposes resolveCode() abstract method so that sub-classes can implement them in their ways. AbstractMessageSource is an example of template method.

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


In the template method of this design pattern, one or more algorithm steps can be overridden by subclasses to allow differing behaviors while ensuring that the overarching algorithm is still followed(Wiki).

The pattern name Template method means what it is. Say we have a method CalculateSomething() and we want to template this method. This method will be declared in the base class a non virtual method. Say the method looks like this.

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

} Step1 and Step2 method implementation can be given by derived classes.

In Strategy Pattern there is no implementation provided by the base (This is the reason why the base is really an interface in the class diagram)

The classic example is sorting. Based on the number of objects needs to be sorted the appropriate algorithm class(merge, bubble, quick etc.) is created and the entire algorithm is encapsulated in each class.

Now can we implement the sorting as a template method? Certainly you can, but you wont find much/any commonality to be abstracted out and placed in the base implementation. So it defeats the purpose of template method pattern.

참고URL : https://stackoverflow.com/questions/669271/what-is-the-difference-between-the-template-method-and-the-strategy-patterns

반응형