2012-03-06 48 views
12

随着问题表明,string.IsNullOrEmpty(myString)或string.IsNullOrWhiteSpace(myString)是否违反SRP规则?

由于我们使用的是像IsNullOrEmpty或IsNullOrWhiteSpace字符串函数的功能显示名称,这些是做一个以上的工作,是不是违反了SRP

而不应该是string.isValid(枚举typeofValidation)比使用战略模式来选择正确的战略来验证。

还是违反工具类或静态类中的SRP是完全可以的。

+3

不要反套,这些功能都很好。 – ken2k 2012-03-06 15:47:39

+0

:),绝对,你是正确的,但有时它会让我困惑很多,所以我想这次,我会问行业专家。 – TalentTuner 2012-03-06 15:49:24

+0

我认为向这两个函数添加任何类似模式会增加代码的混淆性和可读性。只要保持简单(愚蠢) – Alex 2012-03-06 15:49:47

回答

16

SRP表示函数或类应该只有一个理由需要改变。什么是改变的理由?要更改的原因是请求更改的用户。所以一个类或函数应该只有一个请求修改的用户。

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

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

+0

优秀,我得到了我真正想要的。 – TalentTuner 2012-03-07 00:31:54

+0

你有一些书籍的名称可以参考或链接分享? – TalentTuner 2012-03-07 00:34:32

0

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

3

在面向对象编程中,每个对象都应该有一个责任

你描述方法单一职责原则规定:IsNullOrEmpty或IsNullOrWhiteSpace,这也是自描述的他们确实,他们不是对象。 string有一个单一的责任 - 负责文本字符串!

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

+1

您的意思是说SRP只适用于对象,但不适用于操作?我同意评论,不要过度记住它,但我只是想确认我的困惑。 – TalentTuner 2012-03-06 16:02:00

+0

是的,SRP是凝聚力的另一种说法,相当老的OO术语:) – 2012-03-06 16:05:23

+0

但是,因为我相信SRP对于对象级别和方法级别都是有效的,所以两者都必须有单一的变化原因,比如我写了SerilizeAndValidate (ObjectToSerilizeAndValidate),显然这个方法/类正在做两件事情,Serilize和Validation,显然是违反,类中的某些时间方法导致像上面的serilize和validation的例子一样导致维护恶梦 – TalentTuner 2012-03-06 16:10:08

2

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视为单一行为可能是非常合理的。

想象写了一组一步一步的指示对于有经验的用户打开一个文件的“属性”对话框:

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

现在想象写作的人谁之前从未使用鼠标相同的指令:

  • 名次ition鼠标指针在文件图标上
  • 按下并释放鼠标右键
  • 出现一个菜单。将鼠标指针悬停在“属性”字
  • 按位置,然后松开鼠标左键

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

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

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

这可以让你调用一个方法的便利性,同时保留系列化逻辑与验证逻辑的分离,这将使该程序更容易维护。

+0

在ChrisS的回答中看到我的第二个评论。 – TalentTuner 2012-03-06 16:11:27

+0

@Saurabh我添加了一些与该评论相关的想法 – phoog 2012-03-06 16:24:43

+0

:),颇有争议的问题。我可以改变你的论点,但你听起来对我来说很合理,所以接受作为回答 – TalentTuner 2012-03-06 16:29:49

相关问题