战略模式——正确实施

发布于 2024-10-17 05:24:23 字数 780 浏览 7 评论 0 原文

我是第一次使用这种模式,并且使用 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”。

谢谢。

I'm using this pattern for the first time, and using C#.

I just wanted to check that this is the correct implementation.
I have a button on a Winform, and when clicked on that will output some data in a particular format, defined by choosing from a drop down box. Now this may change in the future, hence me using the Strategy pattern to encapsulate what changes.

I have a 'Strategy Interface' that simply exposes a single method: "Display Data()".

On my button click I use the following code:

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


    }

Is this an acceptable way to use this pattern? Obviously if additional output media is identified then I will simply create a new subclass and add an extra 'case' on the switch statement.

Thanks.

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

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

发布评论

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

评论(3

追风人 2024-10-24 05:24:23

使用策略的正确方法是将 IViewData 对象的创建与其使用分开。创建本身可以由工厂方法处理。然后,您可以在单独的位置使用创建的 IViewData,而完全不知道对象的具体类。

例如

private IViewData CreateViewData()
{
    IViewData viewData;

    switch (outputMedia)
    {
        case "Excel":
            viewData = new ExcelOutput(operation, study);
            break;
        case "Spotfire":
            viewData = new SpotfireOutput(operation, study);
            break;
    }
    return viewData;
}

...

private void ConfirmButton_Click(object sender, EventArgs e)
{
    IViewData viewData = CreateViewData();

    viewData.DisplayData();
}

,现在,您可以通过重构工厂方法来进一步改进解决方案。您可能决定使用 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 created IViewData in a separate location, which is totally unaware of the object's concrete class.

E.g.

private IViewData CreateViewData()
{
    IViewData viewData;

    switch (outputMedia)
    {
        case "Excel":
            viewData = new ExcelOutput(operation, study);
            break;
        case "Spotfire":
            viewData = new SpotfireOutput(operation, study);
            break;
    }
    return viewData;
}

...

private void ConfirmButton_Click(object sender, EventArgs e)
{
    IViewData viewData = CreateViewData();

    viewData.DisplayData();
}

Now, from this, you can improve the solution further by refactoring the Factory Method. You may decide to use a Dictionary instead of a switch, or to create the view data objects only once and cache them, or (as you suggested) replacing it with dependency injection ...

聽兲甴掵 2024-10-24 05:24:23

首先,您可以将 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 call DisplayData 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 a Dictionary<string,Func<Operation,Study,IViewData>> instead. But if different classes require different constructors this isn't going to work.

失而复得 2024-10-24 05:24:23

您应该将 switch 语句移至其自己的方法中,最好是在某个控制器类上。这意味着当您需要 IViewData 对象时,不必再次重写开关代码。

private void ConfirmButton_Click(object sender, EventArgs e)
{
    IViewData viewData = ViewDataController.GetViewDataController(outputMedia, operation, study);

   viewData.DisplayData();

}

然后在您的控制器中:

 public class ViewDataController
 {
    public static IViewData GetViewDataController(string outputMedia, string operation, string study)
    {
      IViewData viewData = null;

      switch (outputMedia)
      {
        case "Excel":
            viewData = new ExcelOutput(operation, study);
            break;
        case "Spotfire":
            viewData = new SpotfireOutput(operation, study);
            break;
      }
      return viewData;
     }

这将允许您在整个应用程序中重用相同的代码,如果您需要向 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.

private void ConfirmButton_Click(object sender, EventArgs e)
{
    IViewData viewData = ViewDataController.GetViewDataController(outputMedia, operation, study);

   viewData.DisplayData();

}

And then in your controller:

 public class ViewDataController
 {
    public static IViewData GetViewDataController(string outputMedia, string operation, string study)
    {
      IViewData viewData = null;

      switch (outputMedia)
      {
        case "Excel":
            viewData = new ExcelOutput(operation, study);
            break;
        case "Spotfire":
            viewData = new SpotfireOutput(operation, study);
            break;
      }
      return viewData;
     }

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.

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