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