繁体   English   中英

string.IsNullOrEmpty(myString)或string.IsNullOrWhiteSpace(myString)是否违反了SRP规则?

[英]string.IsNullOrEmpty(myString) or string.IsNullOrWhiteSpace(myString) is not violating SRP Rule?

如问题所示,

由于我们使用像IsNullOrEmpty或IsNullOrWhiteSpace这样的字符串函数作为函数显示的名称,这些函数执行多个作业,是不是违反了SRP

相反,它不应该是string.isValid(Enum typeofValidation)而不是使用策略模式来选择正确的策略进行验证。

或者在实用程序类或静态类中违反SRP是完全可以的。

SRP说一个函数或类应该只有一个改变的理由。 改变的理由是什么? 更改的原因是请求更改的用户。 因此,类或函数应该只有一个请求更改的用户。

现在,一个执行某些计算然后进行一些格式化的函数有两个不同的用户可以请求更改。 一个会请求更改计算,另一个会请求更改格式。 由于这些用户有不同的需求并会提出不同的要求,我们希望他们能够通过不同的功能提供服务。

IsNullOrEmpty(String)不太可能为两个不同的用户提供服务。 关心null的用户可能是关心空的用户,因此isNullOrEmpty不违反SRP。

在面向对象的程序设计中,单一责任原则规定每个对象应该只有一个责任

您正在描述方法:IsNullOrEmpty或IsNullOrWhiteSpace,它们也是自我描述的,它们不是对象。 string有一个责任 - 负责文本字符串!

如果您选择,静态助手可以执行许多任务:单一责任原则的重点是最终使您的代码对于未来的团队和您自己而言更易于维护和可读。 正如评论所说,不要过度思考它。 您不是在这里设计框架,而只是消耗它的一些部分,它将为您清理字符串,并验证传入的数据。

SRP适用于类,而不适用于方法。 尽管如此,让方法只做一件事是个好主意。 但你不能把它变为极端。 例如,如果一个控制台应用程序的Main方法只能包含一个语句(并且如果该语句是一个方法调用,该方法也可以只包含一个语句等,则递归执行),它将毫无用处。

想想IsNullOrEmpty的实现:

static bool IsNullOrEmpty(string s)
{
    return ReferenceEquals(s, null) || Equals(s, string.Empty);
}

所以,是的,它正在做两件事,但它们是在一个表达式中完成的。 如果你进入表达式级别, 任何涉及二进制布尔运算符的布尔表达式都可以说是“做多个事情”,因为它正在评估多个条件的真实性。

如果方法的名称打扰您,因为它们意味着单个方法的活动过多,请将它们包含在您自己的方法中,其名称暗示评估单个条件。 例如:

static bool HasNoVisibleCharacters(string s) { return string.IsNullOrWhitespace(s); }
static bool HasNoCharacters(string s) { return string.IsNullOrEmpty(s); }

回应你的评论:

说我写了像SerilizeAndValidate(ObjectToSerilizeAndValidate)这样的函数,显然这个方法/类,正在做两件事,序列化和验证,显然是一个违规行为,一些类中的方法导致维护噩梦如上面的序列化和验证示例

是的,你关注这一点是正确的,但同样,你不能真正拥有只做一件事的方法。 请记住,不同的方法将处理不同的抽象级别。 您可能有一个非常高级的方法,它将SerializeAndValidate称为长序列操作的一部分。 在该抽象级别,将SerializeAndValidate视为单个操作可能是非常合理的。

想象一下,为有经验的用户编写一套分步说明,打开文件的“属性”对话框:

  • 右键单击该文件
  • 选择“属性”

现在想象一下,为以前从未使用鼠标的人写下相同的说明:

  • 将鼠标指针放在文件的图标上
  • 按下并释放鼠标右键
  • 出现一个菜单。 将鼠标指针放在单词“属性”上
  • 按下并释放鼠标左键

当我们编写计算机程序时,我们需要在两个抽象层次上运行。 或者,相反,在任何给定时间,我们都在一个抽象层次或另一个抽象层面上运作,以免混淆自己。 此外,我们依赖于仍在较低抽象级别运行的库代码。

方法还允许您遵守“不要重复自己”的原则(通常称为“干”)。 如果您需要在应用程序的许多部分中序列化和验证对象,则需要使用SerializeAndValidate方法来减少重复代码。 建议您将该方法实现为一种简单的方便方法:

void SerializeAndValidate(SomeClass obj)
{
    Serialize(obj);
    Validate(obj);
}

这样可以方便地调用一个方法,同时保留序列化逻辑与验证逻辑的分离,这样可以使程序更易于维护。

我不认为这不仅仅是一件事。 它只是确保您的字符串通过所需的条件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM