战略模式——正确实施
我是第一次使用这种模式,并且使用 C#。
我只是想检查这是否是正确的实现。
我在 Winform 上有一个按钮,单击该按钮时将以特定格式输出一些数据,通过从下拉框中选择来定义。现在这将来可能会改变,因此我使用策略模式来封装发生的变化。
我有一个“策略接口”,它只公开一个方法:“显示数据()”。
在我的按钮上单击我使用以下代码:
private void ConfirmButton_Click(object sender, EventArgs e)
{
IViewData viewData;
switch (outputMedia)
{
case "Excel":
viewData = new ExcelOutput(operation, study);
viewData.DisplayData();
break;
case "Spotfire":
viewData = new SpotfireOutput(operation, study);
viewData.DisplayData();
break;
}
}
这是使用此模式的可接受的方式吗?显然,如果识别出其他输出媒体,那么我将简单地创建一个新的子类并在 switch 语句上添加一个额外的“case”。
谢谢。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使用策略的正确方法是将 IViewData 对象的创建与其使用分开。创建本身可以由工厂方法处理。然后,您可以在单独的位置使用创建的 IViewData,而完全不知道对象的具体类。
例如
,现在,您可以通过重构工厂方法来进一步改进解决方案。您可能决定使用
Dictionary
而不是switch
,或者仅创建一次视图数据对象并缓存它们,或者(如您所建议的)用依赖项注入替换它...The proper way to use Strategy would be to separate the creation of the
IViewData
object from its usage. The creation itself might be handled by a Factory Method. Then you can use the createdIViewData
in a separate location, which is totally unaware of the object's concrete class.E.g.
Now, from this, you can improve the solution further by refactoring the Factory Method. You may decide to use a
Dictionary
instead of aswitch
, or to create the view data objects only once and cache them, or (as you suggested) replacing it with dependency injection ...首先,您可以将
viewData.DisplayData();
移出开关。无需对每种情况重复进行。能够以相同的方式为所有这些调用DisplayData
是您首先引入该接口的重点。在每个
case
中以相同的方式传递参数看起来也有点重复。因此,也许可以使用Dictionary>
来代替。但如果不同的类需要不同的构造函数,这就行不通了。First of all you can move
viewData.DisplayData();
out of the switch. No need to repeat it for each case. And being able to callDisplayData
in the same way for all of them is the whole point you introduced that interface in the first place.Passing in the parameters in the same way in every
case
looks a bit repetitive too. So perhaps use aDictionary<string,Func<Operation,Study,IViewData>>
instead. But if different classes require different constructors this isn't going to work.您应该将 switch 语句移至其自己的方法中,最好是在某个控制器类上。这意味着当您需要 IViewData 对象时,不必再次重写开关代码。
然后在您的控制器中:
这将允许您在整个应用程序中重用相同的代码,如果您需要向 switch 语句添加任何条目,那么您只需在一处执行即可。
You should move the switch statement into its own method, ideally on some controller class. This means you dont have to re-write the switch code again when you need an IViewData object.
And then in your controller:
This will allow you to reuse the same code throughout your application, and if you ever need to add any entries to the switch statement then you only have to do it in one place.