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

时间:2010-02-17 14:28:09

标签: design-patterns

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

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

我所指的应用程序是一个将取代旧系统的应用程序。遗留代码将被关闭,并且在某些时候不再使用。一旦到了那个时间点,我就不想再返回并更改任何代码(如果可能的话)。

以下是我所说的psuedo中的一个虚构的概念性例子:

NewSystemEmployee.Save(Employee e)

if (Legacy System Is Running)
{
    LegacySystemEmployee.Save(Employee e)
}

方法NewSystemEmployee.Save总是需要执行。只要Legacy系统正在运行,我只想执行LegacySystemEmployee.Save。 Legacy系统关闭后,我不再想执行LegacySystemEmployee.Save

遗留系统一旦消失,我不知道如何在没有我想要的情况下完成任务:

  1. 在致电LegacySystemEmployee.Save
  2. 之前创建IF声明
  3. 删除对LegacySystemEmployee.Save方法的所有调用或
  4. 更改LegacySystemEmployee.Save方法,使其成为存根,而不再是
  5. 我还要求NewSystemEmployee类不以任何方式引用LegacySystemEmployee类。

    有什么建议吗?

    非常感谢

6 个答案:

答案 0 :(得分:6)

乍一看,这需要Strategy pattern(或实际上Template Method),可能需要Factory Method来控制要使用的策略。示例(伪Java中):

class Saver {
    protected void LegacySave(Employee e)  {}
    public final void Save(Employee e) {
        NewSystemEmployee.Save(e);
        LegacySave(e);
    }
}

class LegacySaver extends Saver {
    protected void LegacySave(Employee e) {
        LegacySystemEmployee.Save(e);
    }
}

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

getSaver().save(employee);

其中getSaver()是工厂方法,它默默地决定向其调用者呈现哪个Saver实现。通常,它可以从配置文件中获取类名。

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

很大程度上取决于您使用的编程语言。例如。在Java / C ++ / C#中,您可以使用dependency injection轻松完成所需的操作;在其他一些语言中,它可能并不那么容易。

答案 1 :(得分:1)

答案 2 :(得分:0)

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

答案 3 :(得分:0)

我认为最合适的模式是strategy design pattern& factory method design pattern

在您的代码中,不要使用旧版/新算法,而应使用策略界面。 您将使用您拥有的工厂方法检索界面。

如果您使用的是Java / C#,您可以使用IoC工具,例如Unity或者弹簧而不是工厂

答案 4 :(得分:0)

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

class LegacySystemEmployeeProxy {
    public Save(Employee employee) {
        if (Legacy System Is Running) {
            LegacySystemEmployee.Save(employee)
        }
    }
}

现在您的原始代码缩减为:

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

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

答案 5 :(得分:0)

我想到了两个解决方案:

  • 如果可用,请使用条件拼写,例如: (C#)
#if (legacy)
   LegacySystemEmployee.Save(Employee e)
#endif
  • 创建一个新方法SaveEmployee,例如(C#)
public static SaveEmployee(Employee e) {
    NewSystemEmployee.Save(Employee e)

    if (Legacy System Is Running) { LegacySystemEmployee.Save(Employee e) }
}

在扩展中,你可以创建一个“服务接口”,它封装了调用两个系统的所有方法。很明显,你可以将方法组合成一个,例如(C#)

public static SaveEmployee(Employee e) {
    NewSystemEmployee.Save(Employee e)

#if (legacy) 
    LegacySystemEmployee.Save(Employee e) 
#endif
}

为了激活相关代码,您必须使用

定义旧标识符
#define legacy

或在complilation期间作为条件编译符号。