C# string.IsNullOrEmpty(myString)或string.IsNullOrWhiteSpace(myString)未违反SRP规则?

C# string.IsNullOrEmpty(myString)或string.IsNullOrWhiteSpace(myString)未违反SRP规则?,c#,solid-principles,single-responsibility-principle,C#,Solid Principles,Single Responsibility Principle,问题表明, 正如函数名所示,我们使用的字符串函数如IsNullOrEmpty或IsNullOrWhiteSpace,它们所做的工作不止一项,这不是违反了吗 与其使用strategey模式选择要验证的正确策略,不如使用string.isValid(Enum typeofValidation) 或者在utilities类或静态类中违反SRP完全可以。我不认为这是在做一件以上的事情。它只是确保字符串通过一个必需的条件 在面向对象编程中,单一责任原则规定每个对象都应具有单一责任 您正在描述方法:IsNu

问题表明,

正如函数名所示,我们使用的字符串函数如IsNullOrEmpty或IsNullOrWhiteSpace,它们所做的工作不止一项,这不是违反了吗

与其使用strategey模式选择要验证的正确策略,不如使用string.isValid(Enum typeofValidation)


或者在utilities类或静态类中违反SRP完全可以。

我不认为这是在做一件以上的事情。它只是确保字符串通过一个必需的条件

在面向对象编程中,单一责任原则规定每个对象都应具有单一责任

您正在描述方法:IsNullOrEmpty或IsNullOrWhiteSpace,它们的功能也是自描述的,它们不是对象<代码>字符串只有一个职责-负责文本字符串


如果您愿意,静态助手可以执行许多任务:单一责任原则的全部要点是最终使您的代码更易于维护和阅读,以供将来的团队和您自己使用。正如评论所说,不要想得太多。您不是在这里设计框架,而是使用框架的某些部分来为您清理字符串,并验证传入的数据。

SRP适用于类,而不是方法。不过,使用只做一件事的方法是个好主意。但你不能走极端。例如,如果控制台应用程序的主方法只能包含一条语句(并且,如果该语句是方法调用,则该方法也只能递归地包含一条语句,等等),那么该应用程序将非常无用

考虑一下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); }
针对你的评论:

假设我编写了SerializeandValidate(ObjectToSerializeandValidate)这样的函数,很明显这个方法/类正在做两件事,序列化和验证,很明显是一个冲突,一个类中的方法有时会导致维护噩梦,就像上面的序列化和验证示例一样

是的,你关注这一点是对的,但是再一次,你不可能真正拥有只做一件事的方法。请记住,不同的方法将处理不同的抽象级别。您可能有一个非常高级的方法,该方法调用
SerializeAndValidate
,作为一长串操作的一部分。在这个抽象级别上,将
序列化和验证
视为一个单独的操作可能是非常合理的

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

  • 右键单击该文件
  • 选择“属性”
现在想象一下,为一个从未使用过鼠标的人编写相同的说明:

  • 将鼠标指针放在文件图标上
  • 按下并释放鼠标右键
  • 出现一个菜单。将鼠标指针放在单词“属性”上
  • 按下并释放鼠标左键
当我们编写计算机程序时,我们需要在两个抽象层次上进行操作。或者,更确切地说,在任何给定的时间,我们都在一个或另一个抽象层次上运行,以避免混淆我们自己。此外,我们还依赖于在较低抽象级别上运行的库代码

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

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

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

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

现在,一个进行一些计算和格式化的函数有两个不同的用户可以请求更改。一个请求更改计算,另一个请求更改格式。由于这些用户有不同的需求,会在不同的时间提出他们的请求,我们希望他们能得到不同的功能


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

不要想得太多,那些函数很好。:),当然,你是对的,但有时它让我很困惑,所以我想这次,我应该问问行业专家。我认为在这两个函数中添加任何类似的模式都会增加代码的混乱和可读性。保持简单(愚蠢)SRP是那些想知道的人的唯一责任原则。从维基百科链接的页面,SRP适用于什么样的事情?
IsNullOrEmpty
就是这样一个例子吗?你的意思是说SRP只适用于对象而不适用于操作吗?我同意这个评论,不要想得太多,但我只是想确认我的困惑。是的,