谁能给我解释一下模板方法模式和策略模式的区别是什么?
据我所知,它们99%是一样的——唯一的区别是 模板方法模式有一个抽象类作为基础 类,而策略类使用已实现的接口 由每个具体的策略类。
然而,就客户端而言,它们是以完全相同的方式被消费的——这是正确的吗?
谁能给我解释一下模板方法模式和策略模式的区别是什么?
据我所知,它们99%是一样的——唯一的区别是 模板方法模式有一个抽象类作为基础 类,而策略类使用已实现的接口 由每个具体的策略类。
然而,就客户端而言,它们是以完全相同的方式被消费的——这是正确的吗?
当前回答
模板方法模式善于阐明算法的整体步骤,而策略模式适合灵活性和可重用性,因此如果需要,可以将策略组合在一起,例如:jdk8中的许多功能接口,如Comparator.reversed().那么比较(Comparator)是策略的一个角色。
模板方法模式侧重于更高的内聚性,而策略模式则与上下文对象松散耦合以分离关注点。
策略易于维护,因为上下文不知道具体的策略,无论主要算法在上下文中发生什么变化都不会影响策略。另一方面,如果在抽象模板类中改变算法的框架,可能会影响其子类的升级。
其他回答
模板模式:
模板方法是关于让子类重新定义算法的某些步骤,而不改变基类中定义的算法的主要结构和步骤。 模板模式通常使用继承,因此可以在基类中提供算法的泛型实现,如果需要,子类可以选择覆盖它。
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存储库。
在策略模式中,子类起主导作用,它们控制算法。这里的代码是跨子类复制的。算法的知识和如何实现它分布在许多类中。
在模板模式中,基类具有算法。它最大化了子类之间的重用。由于算法在一个地方,基类保护它。
模板模式类似于策略模式。这两种模式在范围和方法上有所不同。
策略用于允许调用者改变整个算法,比如如何计算不同类型的税,而模板方法用于改变算法中的步骤。因此,策略的粒度更粗。模板允许在操作序列中进行细粒度的控制,但允许这些细节的实现有所不同。
另一个主要区别是策略使用委托,而模板方法使用继承。在Strategy中,算法被委托给主题将引用的另一个xxxStrategy类,但在Template中,您可以继承基类并重写方法来进行更改。
从http://cyruscrypt.blogspot.com/2005/07/template-vs-strategy-patterns.html
模板方法:
它是基于继承的 定义了不能被子类改变的算法框架。只有某些操作可以在子类中被重写 父类完全控制算法,只与具体类的某些步骤不同 绑定在编译时完成
Template_method结构:
策略:
它基于委托/组合 它通过修改方法行为来改变对象的内容 它用来在一系列算法之间切换 它通过在运行时完全将一种算法替换为另一种算法来改变对象在运行时的行为 绑定在运行时完成
战略结构:
为了更好地理解,请查看Template方法和策略文章。
相关文章:
在JDK模板设计模式中,找不到一个方法定义了一组要按顺序执行的方法
策略模式的真实例子
我认为主要的区别是,有了模板,你需要一个算法来做一些事情,但让我们说,在算法的中间,你想要运行不同的行为,所以你可以发送一个接口的实现,使算法在运行时动态。
但是对于策略,你实际上有完全不同的算法执行而不仅仅是算法的一个变体,然后你选择运行哪个算法,但是模板你只有一个变体的算法。
最后,你可以实现你想要的,使用模板作为策略,反之亦然,但我看到了区别。