战略模式如何工作?
它是如何工作的,它用于什么以及什么时候使用它?
让我们以简单的方式来解释战略模式:
你有一个类Car()
和一个方法run()
,所以你用这种方式使用伪语言:
mycar = new Car() mycar.run()
现在,您可能需要在程序执行时随时更改run()
行为。 例如,您可能想要模拟电机故障或在video游戏中使用“增强”button。
有几种方法可以做这种模拟:使用条件语句和标志variables是一种方法。 策略模式是另一种:它将run()
方法的行为委托给一个子类:
Class Car() { this.motor = new Motor(this) // passing "this" is important for the motor so it knows what it is running method run() { this.motor.run() } method changeMotor(motor) { this.motor = motor } }
如果你想改变汽车的行为,你可以改变电机。 (在现实生活中更容易一个程序,对吧?;-))
如果您有很多复杂的状态,这非常有用:您可以更轻松地更改和维护它们。
问题
策略模式用于解决可能(或可能预见到的)可能通过不同策略实施或解决的问题,并且具有针对这些情况的明确界定的问题。 每个策略都是完全有效的,在某些情况下,某些策略更适合应用程序在运行时间之间进行切换。
代码示例
namespace StrategyPatterns { // Interface definition for a Sort algorithm public interface ISort { void Sort(List<string> list) } // QuickSort implementation public class CQuickSorter : ISort { void Sort(List<string> list) { // Here will be the actual implementation } } // BubbleSort implementation public class CBubbleSort : ISort { void Sort(List<string> list) { // The actual implementation of the sort } } // MergeSort implementation public class CMergeSort : ISort { void Sort(List<string> list) { // Again the real implementation comes here } } public class Context { private ISort sorter; public Context(ISort sorter) { // We pass to the context the strategy to use this.sorter = sorter; } public ISort Sorter { get{return sorter;) } } public class MainClass { static void Main() { List<string> myList = new List<string>(); myList.Add("Hello world"); myList.Add("Another item"); myList.Add("Item item"); Context cn = new Context(new CQuickSorter()); // Sort using the QuickSort strategy cn.Sorter.Sort(myList); myList.Add("This one goes for the mergesort"); cn = new Context(new CMergeSort()); // Sort using the merge sort strategy cn.Sorter.Sort(myList); } } }
- 什么是战略? 战略是旨在实现特定目标的行动计划;
- “定义一个algorithm家族,封装每个algorithm,并使它们可以互换。 策略可以让algorithm独立于使用它的客户。“(四人帮);
- 指定一组类,每个类表示一个潜在的行为。 在这些类之间切换会改变应用程序行为。 (“战略”);
- 这种行为可以在运行时(使用多态)或devise时select;
- 捕获接口中的抽象,在派生类中隐藏实现细节;
- 该策略的替代scheme是通过使用条件逻辑来更改应用程序的行为。 (坏);
-
使用此模式可以更轻松地添加或删除特定的行为,而无需对应用程序的全部或部分进行重新编码和重新testing;
-
良好的用途:
- 当我们有一组类似的algorithm,并且需要在应用程序的不同部分进行切换。 有策略模式可以避免ifs并且易于维护;
- 当我们想向超类添加新的方法时,并不一定对每个子类都有意义。 我们不使用传统方式使用接口,而是添加新方法,而是使用一个实例variables,该variables是新function接口的子类。 这就是所谓的组合:不是通过inheritance来inheritance一个能力,而是用具有正确能力的对象来组成类。
直接从策略模式维基百科文章 :
策略模式对于需要dynamic交换应用程序中使用的algorithm的情况非常有用。 策略模式旨在提供一种方法来定义一系列algorithm,将每个algorithm封装为一个对象,并使它们可以互换。 策略模式让algorithm独立于使用它们的客户端。
添加已经很好的答案:策略模式与将一个或多个函数传递给另一个函数具有很强的相似性。 在策略中,这是通过将所述函数包装在对象中,然后传递该对象来完成的。 有些语言可以直接传递函数,所以根本不需要这个模式。 但其他语言不能传递函数,但可以传递对象; 该模式然后适用。
特别是在类Java的语言中,你会发现语言的types动物园是非常小的,你唯一的方法来扩展它是通过创build对象。 因此,解决问题的大多数办法是想出一个模式; 一种组合对象来实现特定目标的方法。 使用更丰富types的动物园的语言往往有更简单的方法来解决问题 – 但更丰富的types也意味着你不得不花更多的时间来学习types系统。 具有dynamic打字规则的语言通常也会以一种偷偷摸摸的方式解决问题。
一个密切相关的模式是委托模式; 在这两种情况下,一些工作被传递给其他组件。 如果我理解正确,这些模式之间的差异是这样的(如果我错了,请纠正我):
-
在委托模式中,委托由封闭(委托)类实例化; 这允许通过组合而不是inheritance来重用代码。 封闭类可能知道委托的具体types,例如它是否自己调用构造函数(而不是使用工厂)。
-
在Strategy模式中,执行策略的组件是通过其构造函数或setter(根据您的宗教信仰)提供给封闭(使用)组件的依赖项。 使用组件完全不知道正在使用什么策略; 该策略总是通过一个接口来调用。
任何人都知道其他的区别?