我在维基百科上看过这个解释,特别是C++示例,并且没有认识到只定义3个类,创建实例和调用它们之间的区别,以及那个例子.我看到的只是将其他两个类放入流程中,无法看到哪里会有好处.现在我肯定我错过了一些明显的东西(树木) - 有人可以用一个明确的现实世界的例子来解释它吗?
到目前为止,我可以从答案中得到什么,在我看来,这只是一种更为复杂的方式:
have an abstract class: MoveAlong with a virtual method: DoIt() have class Car inherit from MoveAlong, implementing DoIt() { ..start-car-and-drive..} have class HorseCart inherit from MoveAlong, implementing DoIt() { ..hit-horse..} have class Bicycle inherit from MoveAlong, implementing DoIt() { ..pedal..} now I can call any function taking MoveAlong as parm passing any of the three classes and call DoIt Isn't this what Strategy intents? (just simpler?)
[编辑 - 更新]我在上面引用的函数被替换为另一个类,其中MoveAlong属于属性,根据需要根据在这个新类中实现的算法设置.(与接受的答案中的内容类似.)
[编辑 - 更新] 结论
策略模式有它的用途,但我是KISS的坚定信徒,并倾向于更直接和更少的混淆技术.主要是因为我想传递易于维护的代码(并且'我很可能是那些必须进行更改的人!).
关键是将算法分成可在运行时插入的类.例如,假设您有一个包含时钟的应用程序.您可以通过许多不同的方式绘制时钟,但在大多数情况下,底层功能是相同的.所以你可以创建一个时钟显示界面:
class IClockDisplay { public: virtual void Display( int hour, int minute, int second ) = 0; };
然后你有一个连接到计时器的Clock类,每秒更新一次时钟显示.所以你会有类似的东西:
class Clock { protected: IClockDisplay* mDisplay; int mHour; int mMinute; int mSecond; public: Clock( IClockDisplay* display ) { mDisplay = display; } void Start(); // initiate the timer void OnTimer() { mDisplay->Display( mHour, mMinute, mSecond ); } void ChangeDisplay( IClockDisplay* display ) { mDisplay = display; } };
然后在运行时使用正确的显示类来实例化您的时钟.即你可以使用ClockDisplayDigital,ClockDisplayAnalog,ClockDisplayMartian来实现IClockDisplay接口.
因此,您可以稍后通过创建新类来添加任何类型的新时钟显示,而不必弄乱您的Clock类,并且无需覆盖维护和调试可能很麻烦的方法.
在Java中,您使用密码输入流进行解密,如下所示:
String path = ... ; InputStream = new CipherInputStream(new FileInputStream(path), ???);
但是密码流不知道你打算使用什么加密算法或块大小,填充策略等......新算法将一直添加,因此硬编码是不切实际的.相反,我们传入一个Cipher 策略对象来告诉它如何执行解密...
String path = ... ; Cipher strategy = ... ; InputStream = new CipherInputStream(new FileInputStream(path), strategy);
一般来说,你使用的策略模式您有任何知道对象的任何时候有什么需要做的,但不是如何去做.另一个很好的例子是Swing中的布局管理器,虽然在这种情况下它并没有很好的工作,请参阅Totally GridBag以获得一个有趣的插图.
注意:这里有两种模式,因为流中的流包装是Decorator的一个例子.
战略与决策/选择之间存在差异.大多数情况下,我们将在代码中处理决策/选择,并使用if()/ switch()构造实现它们.当需要将逻辑/算法与使用分离时,策略模式很有用.
例如,考虑一种轮询机制,不同的用户会检查资源/更新.现在,我们可能希望通过更快的周转时间或更多详细信息通知一些受益用户.Essentailly使用的逻辑基于用户角色而改变.策略从设计/架构的角度来看是有意义的,在较低的粒度级别,它应该始终受到质疑.