模板方法和策略模式有什么区别?

发布于 2024-07-16 03:43:05 字数 172 浏览 13 评论 0原文

有人可以向我解释一下模板方法模式和策略模式有什么区别吗?

据我所知,它们 99% 是相同的 - 唯一的区别是 模板方法模式有一个抽象类作为基础 类,而策略类使用已实现的接口 由每个具体策略类。

然而,就客户而言,它们的消费方式完全相同 - 这是正确的吗?

Can someone please explain to me what is the difference between the template method pattern and the strategy pattern is?

As far as I can tell they are 99% the same - the only difference being
that the template method pattern has an abstract class as the base
class whereas the strategy class uses an interface that is implemented
by each concrete strategy class.

However, as far as the client is concerned they are consumed in exactly the same way - is this correct?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(19

寄离 2024-07-23 03:43:05

当特定操作具有一些可以根据其他变化的原始行为定义的不变行为时,使用模板模式。 抽象类定义不变的行为,而实现类定义依赖方法。

在策略中,行为实现是独立的——每个实现类都定义行为,并且它们之间没有共享代码。 两者都是行为模式,因此客户的消费方式大致相同。 通常策略有一个公共方法——execute()方法,而模板可以定义一组公共方法以及一组子类必须实现的支持私有原语。

这两种模式可以很容易地一起使用。 您可能有一个策略模式,其中多个实现属于使用模板模式实现的策略系列。

The template pattern is used when a particular operation has some invariant behavior(s) that can be defined in terms of other varying primitive behaviors. The abstract class defines the invariant behavior(s), while the implementing classes defined the dependent methods.

In a strategy, the behavior implementations are independent -- each implementing class defines the behavior and there is no code shared between them. Both are behavioral patterns and, as such, are consumed in much the same way by clients. Typically strategies have a single public method -- the execute() method, whereas templates may define a set of public methods as well as a set of supporting private primitives that subclasses must implement.

The two patterns could easily be used together. You might have a strategy pattern where several implementations belong to a family of strategies implemented using a template pattern.

意犹 2024-07-23 03:43:05

两者之间的主要区别在于具体算法的选择。

使用模板方法模式,这会在编译时通过模板子类化发生。 每个子类通过实现模板的抽象方法来提供不同的具体算法。 当客户端调用模板外部接口的方法时,模板根据需要调用其抽象方法(其内部接口)来调用算法。

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

总结:

  • 模板方法模式:通过子类化进行编译时算法选择
  • 策略模式:通过包含进行运行时算法选择强>

The main difference between the two is when the concrete algorithm is chosen.

With the Template method pattern this happens at compile-time by subclassing the template. Each subclass provides a different concrete algorithm by implementing the template's abstract methods. When a client invokes methods of the template's external interface the template calls its abstract methods (its internal interface) as required to invoke the algorithm.

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

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

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

In contrast, the Strategy pattern allows an algorithm to be chosen at runtime by containment. The concrete algorithms are implemented by separate classes or functions which are passed to the strategy as a parameter to its constructor or to a setter method. Which algorithm is chosen for this parameter can vary dynamically based on the program's state or inputs.

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

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

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

In summary:

  • Template method pattern: compile-time algorithm selection by subclassing
  • Strategy pattern: run-time algorithm selection by containment
合约呢 2024-07-23 03:43:05

我认为两种模式的类图都显示了差异。

策略
将算法封装在类中
图像链接
在此处输入图像描述

模板方法
将算法的确切步骤推迟到子类
图像链接
在此处输入图像描述

I think the Class-Diagrams of both pattern are showing the differences.

Strategy
Encapsulates an algorithm inside a class
Link to image
enter image description here

Template Method
Defer the exact steps of an algorithm to a subclass
Link to Image
enter image description here

时光磨忆 2024-07-23 03:43:05

策略之间的差异策略和模板方法模式 策略与模板方法


相似之处

策略和模板方法模式之间有很多相似之处。 策略和模板方法模式都可以用来满足开闭原则,使软件模块在不改变代码的情况下易于扩展。 两种模式都表示通用功能与该功能的详细实现的分离。 然而,它们在提供的粒度方面略有不同。


差异

以下是我在研究这两种模式时观察到的一些差异:

  1. 在策略中,客户端和策略之间的耦合更多
    松散,而在模板方法中,两个模块更紧密
    耦合。
  2. 在策略中,尽管抽象类可以,但主要使用接口
    也可以根据情况使用,不具体类
    而在 Template 方法中主要使用抽象类或具体方法
    使用类,不使用接口。
  3. 在策略模式中,通常类的整个行为是
    用接口表示,另一方面,使用模板方法
    为了减少代码重复,样板代码定义在
    基础框架或抽象类。 在模板方法中,甚至可以有一个具体的类
    使用默认实现。
  4. 简单来说,你可以改变整个策略(算法)
    策略模式,然而,在Template方法中,只有一些东西
    更改(算法的一部分),其余部分保持不变。 在模板方法中,不变步骤在抽象基类中实现,而
    变体步骤要么给出默认实现,要么不给出
    完全实施。 在模板方法中,组件设计器
    规定了算法所需的步骤以及算法的顺序
    步骤,但允许组件客户端扩展或替换某些
    这些步骤的数量。

图片取自 bitesized 博客。

Difference between Strategy and Template Method Pattern Strategy vs Template method


Similarities

Strategy and Template method patterns have a lot of similarities between them. Both Strategy and Template method patterns can be used for satisfying the Open-Closed Principle and making the software module easy to extend without changing its code. Both patterns represent separation of generic functionality from the detailed implementation of that functionality. However, they differ a little in terms of granularity they offer.


Differences

Here are some of the differences I have observed while studying these two patterns:

  1. In Strategy, the coupling between the client and strategy is more
    loose whereas in Template Method, the two modules are more tightly
    coupled.
  2. In Strategy, mostly an interface is used though abstract class can
    also be used depending on the situation, and concrete class is not
    used whereas in Template method mostly abstract class or concrete
    class is used, interface is not used.
  3. In Strategy pattern, generally entire behaviour of the class is
    represented in terms of an interface, on the other hand, Template method is used
    for reducing code duplication and the boilerplate code is defined in
    base framework or abstract class. In Template Method, there can even be a concrete class
    with default implementation.
  4. In simple words, you can change the entire strategy (algorithm) in
    Strategy pattern, however, in Template method, only some things
    change (parts of algorithm) and rest of the things remain unchanged. In Template Method, the invariant steps are implemented in an abstract base class, while the
    variant steps are either given a default implementation, or no
    implementation at all. In Template method, the component designer
    mandates the required steps of an algorithm, and the ordering of the
    steps, but allows the component client to extend or replace some
    number of these steps.

Image is taken from the bitesized blog.

执笔绘流年 2024-07-23 03:43:05

您可能指的是模板方法模式。
你是对的,他们的需求非常相似。
我想说,如果您有一个“模板”算法,其中定义了子类覆盖这些步骤以更改某些细节的步骤,那么最好使用模板方法。
在策略的情况下,您需要创建一个接口,并且使用委托而不是继承。 我想说这是一个更强大的模式,并且可能更好地符合 DIP - 依赖倒置原则。 它更强大,因为您清楚地定义了策略的新抽象 - 一种做某事的方法,这不适用于模板方法。 所以,如果这个抽象有意义——就使用它。 然而,使用模板方法可以在简单的情况下给你带来更简单的设计,这也很重要。
考虑哪些词更适合:你有模板算法吗? 或者这里的关键是你有一个策略的抽象 - 做某事的新方法

模板方法的示例:

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

在这里,你从 application 继承并替换 init、run 和 did 上将要完成的操作。

策略示例:

array.sort (IComparer<T> comparer)

在这里,当编写比较器时,您不会从数组继承。 数组将比较算法委托给比较器。

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

Example of a template method:

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

Here you inherit from application and substitute what exactly will be done on init, run and done.

Example of a strategy:

array.sort (IComparer<T> comparer)

Here, when writing a comparer, you do not inherit from an array. Array delegates the comparison algorithm to a comparer.

凡间太子 2024-07-23 03:43:05

继承与聚合(is-a 与 has-a)。 这是实现同一目标的两种方法。

此问题显示了选择之间的一些权衡:继承与聚合

Inheritance versus aggregation (is-a versus has-a). It's two ways to achieve the same goal.

This question shows some of trade-offs between choices: Inheritance vs. Aggregation

活泼老夫 2024-07-23 03:43:05

两者非常相似,并且客户端代码都以相似的方式使用它们。 与上面最流行的答案不同,两者都允许在运行时选择算法

两者之间的区别在于,虽然策略模式允许不同的实现使用完全不同的方式来实现所需的结果,但模板方法模式指定了一个总体算法( “模板”方法)用于实现结果——留给具体实现(子类)的唯一选择是所述模板方法的某些细节。 这是通过让模板方法调用一个或多个由子类覆盖(即实现)的抽象方法来完成的,这与模板方法本身不是抽象的并且不被子类覆盖。

客户端代码使用抽象类类型的引用/指针来调用模板方法,该引用/指针指向具体子类之一的实例,该实例可以在运行时确定,就像使用策略模式时一样。

Both are very similar, and both are consumed by the client code in similar ways. Unlike what the most popular answer above says, both allow algorithm selection at run-time.

The difference between the two is that while the strategy pattern allows different implementations to use completely different ways of the achieving the desired outcome, the template method pattern specifies an overarching algorithm (the "template" method) which is be used to achieve the result -- the only choice left to the specific implementations (sub-classes) are certain details of the said template method. This is done by having the the template method make call(s) to one or more abstract methods which are overridden (i.e. implemented) by the sub-classes, unlike the template method which itself is not abstract and not overridden by the sub-classes.

The client code makes a call to the template method using a reference/pointer of the abstract class type pointing to an instance of one of the concrete sub classes which can be determined at run time just like while using the Strategy Pattern.

陌生 2024-07-23 03:43:05

模板方法:

  1. 它基于继承
  2. 定义不能被子类更改的算法骨架。
  3. 子类中只能重写某些操作
  4. 父类完全控制算法
  5. 绑定在编译时完成

策略:

  1. 它基于委托/组合
  2. 它通过修改方法行为来改变对象的内部结构
  3. 它用于在算法系列之间切换
  4. 它通过完全改变对象在运行时的行为
  5. 绑定是在运行时完成的

看看模板方法策略文章以便更好地理解。

相关文章:

JDK 中的模板设计模式,找不到定义要按顺序执行的方法集的方法

策略模式的现实示例

Template Method:

  1. It's based on inheritance
  2. Defines skeleton of algorithm which can't be changed by sub classes.
  3. Only certain operations can be overridden in sub classes
  4. Parent class completely controls the algorithm
  5. Binding is done at compile time

Strategy:

  1. It's based on delegation/composition
  2. It changes guts of the object by modifying method behaviour
  3. It's used to switch between family of algorithms
  4. It changes the behaviour of the object at run time by completely
  5. Binding is done at run time

Have a look at Template method and Strategy articles for better understanding.

Related posts:

Template design pattern in JDK, could not find a method defining set of methods to be executed in order

Real World Example of the Strategy Pattern

痴骨ら 2024-07-23 03:43:05

不,它们不一定以相同的方式消费。 “模板方法”模式是一种为未来的实现者提供“指导”的方式。 您告诉他们,“所有 Person 对象都必须有一个社会安全号码”(这是一个简单的例子,但它正确地表达了这个想法)。

策略模式允许切换多种可能的实现。 它(通常)不是通过继承来实现的,而是让调用者传入所需的实现。 一个示例可能是允许为 ShippingCalculator 提供几种不同的税费计算方式之一(NoSalesTax 实现,或许还有 PercentageBasedSalesTax 实现)。

因此,有时,客户端实际上会告诉对象使用哪种策略。 如

myShippingCalculator.CalculateTaxes(myCaliforniaSalesTaxImpl);

但客户端永远不会对基于模板方法的对象执行此操作。 事实上,客户端甚至可能不知道对象是基于模板方法的。 模板方法模式中的那些抽象方法甚至可能受到保护,在这种情况下,客户端甚至不知道它们的存在。

No, they are not necessarily consumed in the same way. The "template method" pattern is a way of providing "guidance" to future implementers. You are telling them, "All Person objects must have a Social Security Number" (that's a trivial example but it gets the idea across correctly).

The strategy pattern allows multiple possible implementations to be switched in and out. It is not (usually) implemented through inheritance, but instead by letting the caller pass in the desired implementation. An example might be allowing a ShippingCalculator to be provided with one of several different ways of calculating taxes (a NoSalesTax implementation, and a PercentageBasedSalesTax implementation perhaps).

So, sometimes, the client will actually tell the object which strategy to use. As in

myShippingCalculator.CalculateTaxes(myCaliforniaSalesTaxImpl);

But the client would never do that for an object that was based on Template Method. In fact, the client might not even know an object is based on Template Method. Those abstract methods in the Template Method pattern might even be protected, in which case the client wouldn't even know they exist.

和我恋爱吧 2024-07-23 03:43:05

我建议您阅读文章。 它解释了真实案例的差异。

引自文章

正如我们所见,实现类也依赖于模板
方法类。 如果出现以下情况,此依赖性会导致更改模板方法:
人们想要改变算法的一些步骤。 在另一
边策略完全封装了算法。 它给出了
实现类来完整定义算法。 因此如果
任何更改到来都需要更改之前的代码
书面课程。 这是我选择策略的主要原因
设计课程。

模板方法的一个特点是模板方法控制
算法。 在其他情况下这可能是一件好事,但在我看来
问题是这限制了我设计课程。 在另一
边策略不控制算法的步骤,该算法使得
我添加完全不同的转换方法。 因此就我而言
策略帮助我实施。

策略的一个缺点是代码冗余太多,
更少的代码共享。 正如所提供的示例中显而易见的那样
文章我必须在四个类中再次重复相同的代码并且
再次。 因此很难维护,因为如果实施
我们系统的某些部分(例如所有人都通用的步骤 4)被更改,然后我
必须在所有 5 个课程中更新此内容。 另一边,在
模板方法,我只能更改超类,更改是
反映到子类中。 因此模板方法给出了一个非常
冗余量低,代码共享量高
类。

策略还允许在运行时更改算法。 在模板中
方法一必须重新初始化对象。 这个功能的
策略提供了很大的灵活性。 从设计角度来说
认为人们必须更喜欢组合而不是继承。 因此使用
战略模式也成为发展的首要选择。”

I would suggest you to read this article. It explains the differences on a real case example.

Quote from the article

"As one can see implementing classes also depend upon the template
method class. This dependency causes to change the template method if
one wants to change some of the steps of the algorithm. On the other
side strategy completely encapsulates the algorithm. it gives the
implementing classes to completely define an algorithm. Therefore if
any change arrives one does need to change the code for previously
written classes. This was the primary reason I choose strategy for
designing up the classes.

One feature of template method is that template method controls the
algorithm. Which can be a good thing in other situation but in my
problem this was restricting me to design the classes. On the other
side strategy does not control the steps of an algorithm which enables
me to add completely different conversion methods. Hence in my case
strategy helps me for implementation.

One drawback of strategy is that there is too much code redundancy and
less code sharing. As it is obvious in the presented example of this
article I have to repeat the same code in four classes again and
again. Therefore it is hard to maintain because if the implementation
of our system such as step 4 which is common to all is changed then I
will have to update this in all 5 classes. On the other side, in
template method, I can only change the superclass and the changes are
reflected into the sub classes. Therefore template method gives a very
low amount of redundancy and high amount of code sharing among the
classes.

Strategy also allows changing the algorithm at run-time. In template
method one will have to re-initialize the object. This feature of
strategy provide large amount of flexibility. From design point of
view one has to prefer composition over inheritance. Therefore using
strategy pattern also became the primary choice for development."

用心笑 2024-07-23 03:43:05

在策略模式中,子类正在运行并控制算法。 这里的代码在子类中重复。 该算法以及如何实现它的知识分布在许多类中。

在模板模式中,基类有算法。 它最大化了子类之间的重用。 由于算法位于一处,因此基类会保护它。

In strategy pattern subclasses are running the show and they control the algorithm. Here code is duplicated across the subclasses. The knowledge of the algorithm and how to implement it is distributed over many classes.

In template pattern, base class has algorithm. It maximizes the reuse among the subclasses. Since algorithm lies in one place, base class protects it.

何止钟意 2024-07-23 03:43:05

模板模式与策略模式类似。 这两种模式在范围和方法上有所不同。

策略用于允许调用者改变整个算法,例如如何计算不同类型的税,而模板方法用于改变算法中的步骤。 因此,策略的粒度更粗。 该模板允许对操作序列进行更细粒度的控制,但允许这些细节的实现发生变化。

另一个主要区别是策略使用委托,而模板方法使用继承。 在 Strategy 中,算法被委托给主题将引用的另一个 xxxStrategy 类,但使用 Template,您可以对基类进行子类化并重写方法以进行更改。

来自 http://cyruscrypt.blogspot.com/2005/07/ template-vs-strategy-patterns.html

The Template pattern is similar to the Strategy pattern. These two patterns differ in scope and in methodology.

Strategy is used to allow callers to vary an entire algorithm, like how to calculate different types of tax, while Template Method is used to vary steps in an algorithm. Because of this, Strategy is more coarsely grained. The Template allows finer-grained controls in the sequent of operations, and yet allows the implementations of these details to vary.

The other main difference is that Strategy uses delegation while Template Method uses inheritance. In Strategy, the algorithm is delegated to the another xxxStrategy class that the subject will have a reference to, but with Template you subclass the base and override methods to make changes.

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

怂人 2024-07-23 03:43:05

模板模式:

模板方法是让子类重新定义算法的某些步骤,而不改变基类中定义的算法的主要结构和步骤。
模板模式通常使用继承,因此可以在基类中提供算法的通用实现,子类可以根据需要选择覆盖该实现。

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 存储库

Template Pattern:

Template method is about letting subclasses redefine certain steps of the algorithm, without changing the main structure and steps of the algorithm, defined in the base class.
Template pattern usually uses inheritance, so a generic implementation of algorithms can be provided in the base class, which the subclass might choose to override if needed.

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

Note in the above code, the go() algorithm steps will always be the same, but the subclasses might define a different recipe for performing a particular step.

Strategy Pattern:

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.

成熟的代价 2024-07-23 03:43:05

策略设计模式

  • 支持组合。
  • 使您可以灵活地在运行时更改对象的行为。
  • 客户端代码和解决方案/算法代码之间的耦合较少。

模板方法设计模式

  • 优先于继承而不是组合
  • 在基类中定义算法。 可以在子类中自定义各个算法。

Strategy Design Pattern

  • Supports composition.
  • Provides you the flexibility to change the behavior of object at runtime.
  • Less coupling between the client code and the solution/algorithm code.

Template Method Design Pattern

  • Favours inheritance over composition
  • Define algorithm in your base class. Individual pieces of algorithm can be customized in child classes.
同展鸳鸯锦 2024-07-23 03:43:05

它们都是实现相同结果的不同技术,所以问题是何时使用哪种。

  • 如果您使用的框架或库无法访问源代码,并且想要更改类的某些行为,那么您必须使用模板方法。 这意味着简单的继承。
  • 如果您正在开发一个类,并且很明显需要以不同的方式实现某些逻辑部分以处理各种情况,请采用策略模式。 策略比模板方法更可靠。 它涵盖了依赖倒置和开放/关闭原则。 因此它是可扩展的并且也易于测试。
  • 如果您正在开发一个类,并且您不知道将来会发生什么变化,请尽可能将您的逻辑划分为单独的、单一的负责函数。 只是。 (既不是模板方法也不是策略)。

Both of them are different techniques to achieve the same result, so question is to use which when.

  • If you are using a framework or library which you do not have access to the source code and you want to change some behaviors of a class, so you have to go for Template Method. That means inheritance simply.
  • If you are developing a class and it is obvious that some parts of the logic needs to be implemented differently to handle various situations, take the Strategy pattern. Strategy is more SOLID than the Template Method. It covers both Dependency Inversion and Open/Close principles. So it is extendable and also easily testable.
  • If you are developing a class and you do not know what changes will happen in the future, divide your logic into separate and single responsible functions as much as possible. Just that. (Neither Template Method nor Strategy).
方觉久 2024-07-23 03:43:05

策略作为接口公开,模板方法作为抽象类公开。 这通常在框架中大量使用。
例如
Spring框架的MessageSource类是解析消息的策略接口。 客户端使用该接口的特定实现(策略)。

以及同一接口AbstractMessageSource的抽象实现,它具有解析消息的公共实现,并公开resolveCode()抽象方法,以便子类可以按照自己的方式实现它们。 AbstractMessageSource 是模板方法的一个示例。

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

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

丶情人眼里出诗心の 2024-07-23 03:43:05

在此设计模式的模板方法中,子类可以覆盖一个或多个算法步骤,以允许不同的行为,同时确保仍然遵循总体算法(Wiki)。

模式名称模板方法意味着它是什么。 假设我们有一个方法CalculateSomething()并且我们想要模板化这个方法。 该方法将在基类中声明为非虚方法。 说方法看起来像这样。

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

}
Step1和Step2方法的实现可以由派生类给出。

在策略模式中,基类没有提供任何实现(这就是为什么基类在类图中实际上是一个接口的原因)。

经典的例子是排序。 根据需要排序的对象数量,创建适当的算法类(合并、冒泡、快速等),并将整个算法封装在每个类中。

现在我们可以将排序实现为模板方法吗? 当然可以,但是您不会发现太多/任何共性可以被抽象出来并放置在基本实现中。 所以它违背了模板方法模式的目的。

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.

梦中楼上月下 2024-07-23 03:43:05

我认为主要的区别在于,使用模板,您需要一个可以执行某些操作的算法,但是假设在该算法的中间您想要运行不同的行为,以便您可以发送接口的实现,以便在运行时动态地生成该算法。

但通过策略,您实际上拥有完全不同的算法执行,而不仅仅是算法的变体,然后您选择要运行的算法,但模板您只有一个带有变体的算法。

最后,您可以根据需要实施并使用模板作为策略,反之亦然,但我看到了区别。

I think the major difference is that with template you need an algorithm that does something, but lets say in the middle of that algorithm you want to run different behaviours so you can send an implementation of an interface to make that algorithm dynamically in runtime.

but with strategy you have actually totally different algorithms executions no just a variant of the algorithm, then you chose which algo to run, but template you have just one algo with variants.

At the end you can implement as you want and use template as strategy and viceversa but I see a difference.

花伊自在美 2024-07-23 03:43:05

模板方法模式擅长阐明整体算法步骤,而策略模式适合灵活性和可重用性,因此您可以根据需要将策略组合在一起,例如:jdk8中的许多功能接口,例如 Comparator.reversed().thenComparing (Comparator)是策略的一个角色。

模板方法模式是焦点更高内聚,而策略模式是与上下文对象松散耦合以分离关注点。

策略很容易维护,因为上下文不了解具体策略,无论何时上下文中主要算法发生变化都不会影响策略。 另一方面,如果改变了抽象模板类中算法的骨架,可能会影响其子类的升级。

Template method pattern is good at clarify the overall algorithm steps, however Strategy pattern is suitable for flexibility and reusibility, so you can combine strageties together if you need, e.g: many functional interfaces in jdk8 like Comparator.reversed().thenComparing(Comparator) is a role of strategy.

Template method pattern is focus more high cohesion, but Strategy pattern is loosely coupled with context object for separating concerns.

Strategy is easy to maintain since the context has no knowlege about concrete strategies, whenever the mainly algorithm is changed in context doesn't affect the strategies. On the other hand, if you changed the sckeleton of the algorithm in abstract template class maybe affect its subclasses to upgrade.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文