我应该使用哪种设计模式

本文关键字:设计模式 我应该 | 更新日期: 2023-09-27 18:19:51

我有一段逻辑,需要根据类型执行一次或多次(在循环中)。战略模式在这里有意义吗?本质上:

if (type == 1)
{
   ProcessReport("");
}
else if (type == 2)
{
   for (int i = 0; i < numUsers; i++)
   {
     ProcessReport(userId);
   }
}
public void ProcessReport(string id)
{
   if (id == "")
   {
     //Send full report
   }
   else
   {
     GetReportFragment();
     //Send report
   }
}

我应该使用哪种设计模式

好吧,因为您显然使用了"类型代码"来区分不同的行为,所以您可以从用子类(多态性)替换它开始。当存在基于类型代码的分支时,这通常是要做的第一件事。

然而,对于简单的问题,这可能有些过头了。你的代码更令人反感的是:

  • 对类型使用幻数:您至少应该将它们更改为枚举以提高可读性
  • 传递空参数"")以指示特定行为:如果没有要指定的ID,则至少为"完整报告"创建一个单独的方法

策略模式通常定义一系列算法,封装每一个算法,并使它们可互换。策略允许算法与使用它的客户端独立变化

我没有看到任何复杂的算法值得为其添加另一层抽象

如果您想封装ProcessReport行为,我会创建一个表示该行为的接口,这样您就可以在循环中调用IProcessReport.Process(userId)

根据type变量的语义,使用多态性可能是有意义的。

在当前的例子中,这可能是开销(只有两个分支),但每次看到像if() ... else if() ... else if() ...switch() { case: ... }这样的结构时,你都会想:会有多少个条件分支?将来有可能出现新的吗?

根据这些问题的答案,我们可能会决定用多态性替换条件重构。

您的代码可以简化为:

if (type == 1)
    SendFullReport();
else if (type == 2)
    for (int i = 0; i < numUsers; i++)
        GetReportFragment(userId);

当然,您必须实现SendFullReport()GetReportFragment(string userId)方法。

在这种情况下使用复杂的设计模式是没有意义的。

所以,这只是一个例子,还是实际大小?我的意思是,如果你有两种类型,最好的模式是保持简单:)。

如果您有几种类型,那么您可以在那里有一个策略,或者有一个字典类型的委托/命令,其中包含要执行的代码。

尽管当前函数很简单,但我觉得策略模式是正确的解决方案。通常,我会避免使用"if"语句,并尝试将代码原子化。Groo对代码"气味"的观察也是我的。多态性(策略)可能看起来有些过头了,但我宁愿使用一个稍微抽象一点的解决方案,而不是试图基于一个字符串参数(希望是空的或数字)来改变函数的行为。