策略模式 - 多个返回类型/值 [英] Strategy Pattern - multiple return types/values

查看:206
本文介绍了策略模式 - 多个返回类型/值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在使用C#和EmguCV进行图像处理项目。我们的团队由3人组成。为了取得更快的进展,我们3个人同时处理不同的子问题或尝试不同的算法。



目前,我们每个人都创建一个包含我们正在工作的主要代码,我们所有人都对驱动程序进行了更改,以添加对我们的新功能的调用。所有这些都发生在同一个文件上。我们正在使用源代码管理,所以我们还没有进入对方脚本。但是,我认为这是可持续的,因为我们取得更大的进步。另外,我觉得代码越来越乱了。



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



但是,我意识到这种方法可能会有一些问题:


$不同的算法需要不同的输入(源图像,一些不同的参数集合等)。
  • 不同的算法返回不同的输出(新的图像,特征设置,矩阵等)

  • 第一个问题我相信我可以通过这样做来克服

      Class Strategy1:IStrategy 
    {
    int _code;

    //根据策略类型可以在
    //构造函数中传递不同的* input * paramteres策略
    public Strategy1(int c)
    {
    _code = c;
    }

    //这是IStrategy界面中定义的方法
    public void execute()
    {
    //使用_code和做一些处理在这里
    }
    }

    我可以更改构造函数不同的策略,所以他们可以采取不同类型的参数。



    当我想到如何处理返回多个类型/值的问题时,首先我可以想到的是将执行的返回类型从void更改为哈希表,其中可以存储和返回不同的返回参数具有类的其他成员,如 int _returnCode ,可以通过其他方法或通过该类的只读属性来检索。



    我不确定一个解决方案有多好这将是设计原则,并将乐意听到您的意见。谢谢

    解决方案

    如果算法唯一的共同之处在于它们执行,那么您应该考虑命令模式,而不是策略模式。 (至少,最适合您所描述的解决方案。)



    这很好!它不会为您的战略格局提供细粒度的维系,但听起来好像您无法做到这一点。命令模式将让您保持特定于算法的代码与处理流程控制(驱动程序,从其声音)分离。



    例如,它会让你写这样的代码:

      // ...获取图像和处理应用程序流的逻辑... 

    //我在这里使用'image'作为单个对象的备用项,所有的命令
    //可以从所有输入的容器中导出输入。如果没有这样的
    //对象存在,只需要做你需要构造的命令。
    ICommand [] commands = ImageCommandFactory.CreateCommands(image);

    foreach(命令中的ICommand命令){
    command.Execute();
    }

    // ...处理命令...

    如上所述,命令对象将使用公共成员来公开其执行结果 - 最简单的形式将使用一个属性,如 public object Result {get; } 。 (当然,你可以把这个返回值缩小到一个标准的 ICommandResults 类型,你会越多越好。)



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

      //选择正确的类型的处理器,取决于命令
    IResultHandler handler = ResultHandlerFactory.CreateHandler(command,form);

    //将结果呈现给提供给工厂方法的表单
    handler.RenderResults();

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


    We are working on an image processing project using C# and EmguCV. Our team is composed of 3 people. To make faster progress, the 3 of us work on different sub-problems or experiment with different algorithms at the same time.

    Currently each of us creates a function that contains the major code we are working at and all of us make changes to the driver to add calls to our new functions. All this happens on the same file. We are using source control, so we have not stepped into each other toes yet. But I don't think this will be sustainable as we make more progress. Also, I feel the code is getting messier.

    I was thinking it may be better for us to implement the Strategy pattern and encapsulate our algorithms or sub-problem processing into classes of their own and call the execute method on each from the driver.

    However I realize there may be some problems with this approach:

    1. Different algorithms take different inputs (source image, some different set of parameters etc)
    2. Different algorithms return different outputs (new image, feature set, a matrix etc)

    The first problem I believe I can overcome by doing something like this

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

    I can change the constructors for the different strategies so they can take in different types of arguments.

    When I think about how to deal with the issue of returning multiple types/values, the first thing I can think of is to change execute's return type from void to something like a hash table, where the different return parameters can be stored and returned OR have other members of the class, like "int _returnCode" which can be retrieved by another method or through read-only properties of that class.

    I am not sure how good a solution this would be in terms of design principles, and would be happy to hear your opinion on this. Thanks

    解决方案

    If the only thing the algorithms have in common is that they execute, you should be thinking about the command pattern rather than the strategy pattern. (At least, that best fits the solution you've described.)

    This is fine! It doesn't buy you the fine-grained sustitutability of the strategy pattern, but it doesn't sound like you're in a position to do that. The command pattern will let you keep your algorithm-specific code separate from your processing flow control (the driver, from the sound of it).

    For example, it would let you write code like this:

    // ... 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 ...
    

    As you mentioned, command objects would use public members to expose the results of their execution - the simplest form would use a property like public object Results { get; }. (Of course, the more you can narrow that return value down to a standard ICommandResults type, the better off you'll be.)

    How you handle results is up to you. You could use a factory (again) to create a handler suitable for the command you pass it:

    // 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();
    

    Or use some other technique that fits your design better.

    这篇关于策略模式 - 多个返回类型/值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆