【问题标题】:How to refactor this method to reduce its cognitive complexity如何重构此方法以降低其认知复杂性
【发布时间】:2021-05-05 13:20:46
【问题描述】:

我需要帮助,我正在尝试重构此方法以降低其认知复杂性 sonarqube 显示这个问题

private void PopulateBook(Book b)
{
    if (b.page.num001 == null) b.page.num001 = string.Empty;
    if (b.page.num002 == null) b.page.num002 = string.Empty;
    if (b.page.num003 == null) b.page.num003 = string.Empty;
    if (b.page.num004 == null) b.page.num004 = string.Empty;
    if (b.page.num005 == null) b.page.num005 = string.Empty;
    if (b.page.num006 == null) b.page.num006 = string.Empty;
    if (b.page.num007 == null) b.page.num007 = string.Empty;
    if (b.page.num008 == null) b.page.num008 = string.Empty;
    if (b.page.num009 == null) b.page.num009 = string.Empty;
    if (b.page.num010 == null) b.page.num010 = string.Empty;
    if (b.page.num011 == null) b.page.num011 = string.Empty;
    if (b.page.num012 == null) b.page.num012 = string.Empty;
    if (b.page.num013 == null) b.page.num013 = string.Empty;
    if (b.page.num014 == null) b.page.num014 = string.Empty;
    if (b.page.num015 == null) b.page.num015 = string.Empty;
    if (b.page.num016 == null) b.page.num016 = string.Empty;
    if (b.page.num017 == null) b.page.num017 = string.Empty;
    if (b.page.num018 == null) b.page.num018 = string.Empty;
    if (b.page.num019 == null) b.page.num019 = string.Empty;
    if (b.page.num020 == null) b.page.num020 = string.Empty;
}

【问题讨论】:

  • 什么是b.page?我猜它有 20 个编号的字段?你能多介绍一点上下文吗?
  • 首先将所有这些字段/属性放入单个数组或列表中。然后你可以循环并做一行if
  • 我认为你可以完全摆脱这段代码,毕竟。
  • 使 pages/nums 可枚举可能是最好的解决方案。如果这是不可能的并且您的语言版本是 C# 8.0 或更高版本,您也可以考虑使用null-coalescing assignment operator??=。例如。 b.page.num001 ??= string.Empty;.

标签: c# asp.net .net c#-4.0 c#-3.0


【解决方案1】:

您可以重新设计 Page 类。

我不知道 num001 等是什么,指的是页面上的数字。是单词索引吗? 字符数,具体字符? 还是完全不同的东西?

但不管它是什么:

public class Page {

   public List<Num> numList

   public Page()
   {
      NumList = InitializeNumList();
   }

   private List<Num> InitializeNumList()
   {
      NumList = new List<Num>{};
      for(int i = 0; i < 20; i++)
      {
          NumList.add(new Num(i))
      }
   }

} 

public class Num
{
   public int Id {get;set;};
   public string SomeString {get;set;}

   public Num(int id)
   {
       Id = id;
       SomeString = "";
   }
}

【讨论】:

  • 那么你有一个包含一个 int 的对象列表......你赢了什么?你把明显的字符串值放在哪里了?
  • 显然这里没有分支。复杂性降低。编辑 Num,有一个字符串
  • 此外,重置字符串非常容易。您可以构建一个适当的 for-each 循环并将它们全部重置。
  • 再看看
  • 如果我们新增“num”应该代表什么,这将非常有帮助?
【解决方案2】:

如果您想减少代码行数并假设您的“页面”是仅具有这些属性的类 - 那么您可以使用某种反射来使用循环设置属性。

  private static void PopulateBook(Book b)
        {
            var page = b.page;
            PropertyInfo[] properties = typeof(page).GetProperties();
            foreach(var prop in properties)
            {
                if(prop.GetValue(page) == null)
                prop.SetValue(page, String.Empty);
            }
        }

【讨论】:

  • 我不认为反射会提高代码的认知复杂性(这是问题所要求的)。
  • 请不要在每次觉得需要“修补”糟糕的架构时都进行反思。除了维护地狱之外,这让你无处可去。
猜你喜欢
  • 1970-01-01
  • 2018-09-19
  • 2021-06-29
  • 2021-10-31
  • 1970-01-01
  • 2019-03-08
  • 1970-01-01
  • 2021-01-23
  • 2019-11-02
相关资源
最近更新 更多