gpt4 book ai didi

c# - 哪个优先 : Don't Repeat Yourself or the Single Responsibility Principle?

转载 作者:行者123 更新时间:2023-11-30 13:46:09 26 4
gpt4 key购买 nike

在升级一些旧代码时,我发现这两个 OO 原则似乎相互冲突。

考虑以下伪代码(这是我遇到的简化版本):

int numberOfNewRecords;
int numberOfOldRecords;
int numberOfUndefinedRecords;

void ColourAndCount()
{
foreach(Row row in dataGridView1.Rows)
{
switch(row.Cells["Status"])
{
case: "Old"
row.BackColor = Color.Red;
numberOfOldRecords++;
break;
case: "New"
row.BackColor = Color.Blue;
numberOfNewRecords++;
break;
default:
row.BackColor = Color.White;
numberOfUndefinedRecords++;
break;
}
}
}

这段代码做了两件事:它根据记录的状态计算记录的数量,它还根据它们的状态为每一行着色。这很困惑,但由于这两个操作(到目前为止)总是同时被调用,所以它没有造成任何问题,并且使维护要求(如额外的状态)易于添加。

尽管如此,单一职责原则告诉我应该将其拆分为两个单独的方法:

(编辑)小注:我刚刚意识到我可能在这里误用了术语“单一职责原则”,据我所知,它指的是类。 “一个方法一个操作”设计模式的术语是什么?

int numberOfNewRecords;
int numberOfOldRecords;
int numberOfUndefinedRecords;

void Count()
{
foreach(Row row in dataGridView1.Rows)
{
switch(row.Cells["Status"])
{
case: "Old"
numberOfOldRecords++;
break;
case: "New"
numberOfNewRecords++;
break;
default:
numberOfUndefinedRecords++;
break;
}
}
}

void Colour()
{
foreach(Row row in dataGridView1.Rows)
{
switch(row.Cells["Status"])
{
case: "Old"
row.BackColor = Color.Red;
break;
case: "New"
row.BackColor = Color.Blue;
break;
default:
row.BackColor = Color.White;
break;
}
}
}

但是这违反了不要重复自己:loop 和 switch 语句在两种方法中都是重复的,并且由于此代码最有可能的升级路径是添加其他 Status,因此它使 future 的升级更加困难而不是更少。

我无法找出最优雅的方式来重构它,所以我觉得最好问问社区,以防我遗漏了一些明显的东西。你会如何处理这种情况?

(编辑)

我想出了一个可能的解决方案,但在我看来它像是过度设计一个简单问题的例子(而且它并没有真正解决最初的单一职责问题)。

struct Status
{
public string Name,
public int Count,
public Color Colour,
}

Dictionary<string, Status> StatiiDictionary = new Dictionary<string, int>();
void Initialise()
{
StatiiDictionary.Add(new Status("New", 0, Color.Red));
StatiiDictionary.Add(new Status("Old", 0, Color.Blue));
StatiiDictionary.Add(new Status("Undefined", 0, Color.White));
}

void ColourAndCountAllRows()
{
foreach(Row row in dataGridView1.Rows)
{
CountRow(row, StatiiDictionary);
ColourRow(row, StatiiDictionary);
}
}

void CountRow(Row row, Dictionary<string, Status> StatiiDictionary)
{
StatiiDictionary[row.Cells["Status"]].Count++;
}

void ColourRow(Row row, Dictionary<string, Status> StatiiDictionary)
{
row.BackColour = StatiiDictionary[row.Cells["Status"]].Colour;
}

最佳答案

出于实用的原因,需要不时违反许多编程规则。在你的情况下,我同意 DRY 和 SRP 似乎在竞争,所以我会建议两个标准来决定获胜者:

  1. 代码遵守每一个意味着什么。
  2. 应用程序遵守每一个意味着什么。

在这种情况下,两次枚举网格行的低效率对我来说似乎是最重要的因素,而 DRY 将胜出在这种特殊情况下。在其他一些情况下,情况可能恰恰相反。

添加注释来解释您所做的决定以及原因是值得的,这样以后查看代码的任何人都会清楚。这正是应该使用注释的那种事情,即为什么代码正在做它正在做的事情,而不仅仅是它正在做的事情。

关于c# - 哪个优先 : Don't Repeat Yourself or the Single Responsibility Principle?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23097222/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com