Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns 我应该使用什么设计模式来完成下面的任务_Design Patterns - Fatal编程技术网

Design patterns 我应该使用什么设计模式来完成下面的任务

Design patterns 我应该使用什么设计模式来完成下面的任务,design-patterns,Design Patterns,我需要能够有条件地执行一个方法。我不喜欢在我的代码中使用一堆IF语句,原因有几个,最值得注意的是,在将来的某个时候,该方法将不再使用 我不确定这样做的最佳方式,或者我应该选择什么模式来完成这项任务 我提到的应用程序是一个将要取代传统系统的应用程序。旧代码将被关闭,在某个时候不再使用。一旦那个时间点到来,我就不想回去更改任何代码(如果可能的话) 以下是我的意思在psuedo中虚构的概念示例: NewSystemEmployee.Save(Employee e) if (Legacy System

我需要能够有条件地执行一个方法。我不喜欢在我的代码中使用一堆IF语句,原因有几个,最值得注意的是,在将来的某个时候,该方法将不再使用

我不确定这样做的最佳方式,或者我应该选择什么模式来完成这项任务

我提到的应用程序是一个将要取代传统系统的应用程序。旧代码将被关闭,在某个时候不再使用。一旦那个时间点到来,我就不想回去更改任何代码(如果可能的话)

以下是我的意思在psuedo中虚构的概念示例:

NewSystemEmployee.Save(Employee e)

if (Legacy System Is Running)
{
    LegacySystemEmployee.Save(Employee e)
}
始终需要执行方法
NewSystemEmployee.Save
。只要旧系统还在运行,我只想执行
legacystememployee.Save
。一旦旧系统关闭,我就不想再执行
legacystememployee.Save

一旦遗留系统消失,我不知道如果没有:

  • 在调用LegacySystemEmployee.Save之前创建IF语句
  • 删除对LegacySystemEmployee.Save的每次调用
  • 更改LegacySystemEmployee.Save方法,使其成为存根,仅此而已
  • 我还要求
    NewSystemEmployee
    类不以任何方式引用
    legacystemployee

    有什么建议吗


    非常感谢Aspects将为您提供帮助,您可以从外部代码在方法之前/之后注入一些行为。不知道您使用的是什么技术,所以您需要自己寻找合适的AOP实现。

    乍一看,这需要(或实际上)控制使用哪种策略。示例(在伪Java中):

    由于在某个时间点您将不再需要遗留调用,因此将默认的
    LegacySave
    实现为空是有意义的。然后您可以像这样简单地使用该类:

    getSaver().save(employee);
    
    其中
    getSaver()
    是工厂方法,它以静默方式决定向其调用者呈现哪个
    Saver
    实现。很简单,它可以从配置文件中获取类名

    问题是,您需要如何更改行为:运行时,还是重新启动应用程序?如果可以重新启动应用程序,则很容易更改配置中控制要使用的策略的那一行。在飞行中改变行为稍微有些棘手,但却是可行的


    很大程度上取决于您使用的编程语言。例如在爪哇/C++/C++中,你可以很容易地完成你想要的东西;在其他一些语言中可能没有那么容易。

    我认为最适合您的情况的模式是

    在代码中,不要参考传统/新算法,而是参考策略界面。 您将使用已有的工厂方法检索接口


    如果您使用的是Java/C#,那么您可以使用IoC工具,比如Unity或spring来代替/除了您的工厂之外

    我建议使用策略模式或模板方法模式

    一些链接:


    我会选择简单的代理,它看起来像是遗留系统,但会检查它是否正在运行,并在这种情况下将操作委托给它:

    class LegacySystemEmployeeProxy {
        public Save(Employee employee) {
            if (Legacy System Is Running) {
                LegacySystemEmployee.Save(employee)
            }
        }
    }
    
    现在,您的原始代码简化为:

    NewSystemEmployee.Save(employee)
    LegacySystemEmployeeProxy.Save(employee)
    

    当遗留系统消失时,您可以将LegacySystemEmployeeProxy.Save更改为空方法。

    我立刻想到两种解决方案:

    • 如果条件补偿可用,则使用条件补偿,例如(C#)
    • 创建一个新方法SaveEmployee,例如(c#)
    作为扩展,您可以创建一个“服务接口”,封装调用这两个系统的所有方法。显然,你可以将方法组合成一个,例如(C#)

    为了使Conional代码处于活动状态,您必须使用

    #define legacy

    或者在编译过程中作为条件编译符号。

    是的,我计划重新启动应用程序。Peter,这看起来是实现我需要的功能的一个非常好的方法。我有一个稍微不同的方法来做这件事。下面的代码是c#class Saver{public void Save(Employee e){NewSystemEmployee.Save(e);}}class LegacySaver:Saver{public void Save(Employee e){base.Save(e);//NewSystemEmployee legacystemployee(e);}工厂仍将决定使用哪个Saver实现。我想知道你对我想出的方法有什么看法?你觉得有什么问题吗?感谢您对代码的糟糕格式。当我保存我写的东西时,我遇到了一个问题。您编写的代码和我发布的代码(mis)之间有两个区别。1.Saver类没有引用LegacySave方法。2.LegacySaver类同时调用NewSystemEmployee.Save和LegacySystemployee.Save方法。你认为我提出的方法有什么问题吗?Thanks@mikener差别很小,两种解决方案都有效。你的有一个额外的好处,一旦你摆脱了LegacySaver,你就不需要再碰它了。一般来说,我的示例更健壮(因为子类不能忘记在重写的save()中调用基类方法),但我想在这种情况下,对于单个临时子类,您可能不需要这种健壮性。在我的解决方案中,在删除LegacySaver之后,您必须删除Saver.LegacySave()。@Peter-非常感谢您的帮助。这是我第一次使用StackOverflow。这不会是我的最后一次。谢谢
    #if (legacy)
       LegacySystemEmployee.Save(Employee e)
    #endif
    public static SaveEmployee(Employee e) {
        NewSystemEmployee.Save(Employee e)
    
        if (Legacy System Is Running) { LegacySystemEmployee.Save(Employee e) }
    }
    public static SaveEmployee(Employee e) {
        NewSystemEmployee.Save(Employee e)
    
    #if (legacy) 
        LegacySystemEmployee.Save(Employee e) 
    #endif
    }
    
    #define legacy