策略模式 - 多种返回类型/值

时间:2009-11-14 16:48:07

标签: c# design-patterns design-principles

我们正在使用C#和EmguCV开发图像处理项目。我们的团队由3人组成。为了加快进度,我们三个人同时处理不同的子问题或者尝试不同的算法。

目前,我们每个人都创建了一个函数,其中包含我们正在处理的主要代码,并且我们所有人都对驱动程序进行了更改以添加对新函数的调用。所有这些都发生在同一个文件中。我们正在使用源代码控制,所以我们还没有相互进入脚趾。但我认为,随着我们取得更多进展,这将是可持续的。此外,我觉得代码变得更加混乱。

我认为我们可能更好地实现策略模式并将我们的算法或子问题处理封装到自己的类中,并从驱动程序调用每个类的执行方法。

但是我意识到这种方法可能存在一些问题:

  1. 不同的算法采用不同的输入(源图像,一些不同的参数集等)
  2. 不同的算法返回不同的输出(新图像,特征集,矩阵等)
  3. 我认为我可以通过做这样的事情来克服第一个问题

    Class Strategy1 : IStrategy
    {
        int _code;
    
        // Different *input* paramteres for the strategy may be passed in the 
        // constructor depending on the type of strategy
        public Strategy1(int c)
        {
            _code = c;
        }
    
        // This is the method defined in the IStrategy interface
        public void execute()
        {
            // Some code that uses _code and does some processing goes here
        }
    }
    

    我可以为不同的策略更改构造函数,以便它们可以接受不同类型的参数。

    当我考虑如何处理返回多个类型/值的问题时,我能想到的第一件事就是将执行的返回类型从void更改为类似哈希表的东西,其中可以存储不同的返回参数并返回 OR 有该类的其他成员,例如“int _returnCode”,可以通过其他方法或该类的只读属性检索。

    我不确定这在设计原则方面有多好,并且很乐意听取您的意见。感谢

3 个答案:

答案 0 :(得分:4)

如果算法的唯一共同点是它们执行,那么你应该考虑command pattern而不是策略模式。 (至少,这最符合你所描述的解决方案。)

这很好!它并没有为你带来策略模式的细粒度可持续性,但听起来并不像你能做到这一点。命令模式将允许您将特定于算法的代码与处理流控制(驱动程序,从它的声音)分开。

例如,它可以让你编写这样的代码:

// ... logic to obtain an image and handle application flow ...

// I'm using 'image' here as a stand-in for a single object all your commands
// could derive their inputs from, or a container of all the inputs. If no such
// object exists, just do what you have to construct the commands.
ICommand[] commands = ImageCommandFactory.CreateCommands(image);

foreach(ICommand command in commands) {
    command.Execute();
}

// ... Handle commands ...

正如您所提到的,命令对象将使用公共成员公开其执行结果 - 最简单的形式将使用public object Results { get; }之类的属性。 (当然,您可以将返回值缩小到标准ICommandResults类型的越多,您的情况就越好。)

您如何处理结果取决于您。您可以使用工厂(再次)创建适合您传递的命令的处理程序:

// Picks the correct type of processor, depending on the command
IResultHandler handler = ResultHandlerFactory.CreateHandler(command, form);

// renders the results to the form provided to the factory method
handler.RenderResults();

或者使用其他更适合您设计的技术。

答案 1 :(得分:0)

这里有几件事:

  • 将所有内容都放在一个文件中是一种反模式的“泥球大”
  • 您可以使用部分类将其拆分为多个文件,这解决了许多人在同一个文件上工作的问题,但只是稍微好一些。
  • 为什么不只是创建帮助程序类(帮助程序模式),而不是策略模式,可以测试每个帮助程序。

答案 2 :(得分:0)

如果您可以自由使用C#4,则可以依赖covariant返回类型功能。 这样您就可以将执行界面定义为:

public object execute()

然后在派生类中覆盖它,返回类型特定于该具体类。