简体   繁体   English

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

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

As the question shows, 如问题所示,

As we are using string functions like IsNullOrEmpty or IsNullOrWhiteSpace as the name of functions shows , these are doing more than one job , is it not a violation of SRP ? 由于我们使用像IsNullOrEmpty或IsNullOrWhiteSpace这样的字符串函数作为函数显示的名称,这些函数执行多个作业,是不是违反了SRP

rather should it not be string.isValid(Enum typeofValidation) than using strategey pattern to choose the correct strategey to validate. 相反,它不应该是string.isValid(Enum typeofValidation)而不是使用策略模式来选择正确的策略进行验证。

or is it perfectly OK to violate SRP in utilities class or static classes. 或者在实用程序类或静态类中违反SRP是完全可以的。

The SRP says that a function or class should have only one reason to change. SRP说一个函数或类应该只有一个改变的理由。 What is a reason to change? 改变的理由是什么? A reason to change is a user who requests changes. 更改的原因是请求更改的用户。 So a class or function should have only one user who requests changes. 因此,类或函数应该只有一个请求更改的用户。

Now a function that does some calculations and then some formatting, has two different users that could request a change. 现在,一个执行某些计算然后进行一些格式化的函数有两个不同的用户可以请求更改。 One would request changes to the calculations and the other would request changes to the formatting. 一个会请求更改计算,另一个会请求更改格式。 Since these users have different needs and will make their requests and different times, we'd like them to be served by different functions. 由于这些用户有不同的需求并会提出不同的要求,我们希望他们能够通过不同的功能提供服务。

IsNullOrEmpty(String) is not likely to be serving two different users. IsNullOrEmpty(String)不太可能为两个不同的用户提供服务。 The user who cares about null is likely the same user who cares about empty, so isNullOrEmpty does not violate the SRP. 关心null的用户可能是关心空的用户,因此isNullOrEmpty不违反SRP。

In object-oriented programming, the single responsibility principle states that every object should have a single responsibility 在面向对象的程序设计中,单一责任原则规定每个对象应该只有一个责任

You're describing methods: IsNullOrEmpty or IsNullOrWhiteSpace, which are also self-describing in what they do, they're not objects. 您正在描述方法:IsNullOrEmpty或IsNullOrWhiteSpace,它们也是自我描述的,它们不是对象。 string has a single responsibility - to be responsible for text strings! string有一个责任 - 负责文本字符串!

Static helpers can perform many tasks if you choose: the whole point of the Single Responsibility principle is to ultimately make your code more maintainable and readable for future teams and yourself. 如果您选择,静态助手可以执行许多任务:单一责任原则的重点是最终使您的代码对于未来的团队和您自己而言更易于维护和可读。 As a comment says, don't overthink it. 正如评论所说,不要过度思考它。 You're not designing the framework here but just consuming some parts of it that will clean your strings for you, and validate incoming data. 您不是在这里设计框架,而只是消耗它的一些部分,它将为您清理字符串,并验证传入的数据。

The SRP applies to classes, not methods. SRP适用于类,而不适用于方法。 Still, it's a good idea to have methods that do one thing only. 尽管如此,让方法只做一件事是个好主意。 But you can't take that to extremes. 但你不能把它变为极端。 For example, a console application would be fairly useless if its Main method could contain only one statement (and, if the statement is a method call, that method could also contain only one statement, etc., recursively). 例如,如果一个控制台应用程序的Main方法只能包含一个语句(并且如果该语句是一个方法调用,该方法也可以只包含一个语句等,则递归执行),它将毫无用处。

Think about the implementation of IsNullOrEmpty: 想想IsNullOrEmpty的实现:

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

So, yes, it's doing two things, but they're done in a single expression. 所以,是的,它正在做两件事,但它们是在一个表达式中完成的。 If you go to the level of expressions, any boolean expression involving binary boolean operators could be said to be "doing more than one thing" because it is evaluating the truth of more than one condition. 如果你进入表达式级别, 任何涉及二进制布尔运算符的布尔表达式都可以说是“做多个事情”,因为它正在评估多个条件的真实性。

If the names of the methods bother you because they imply too much activity for a single method, wrap them in your own methods with names that imply the evaluation of a single condition. 如果方法的名称打扰您,因为它们意味着单个方法的活动过多,请将它们包含在您自己的方法中,其名称暗示评估单个条件。 For example: 例如:

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

In response to your comment: 回应你的评论:

say I wrote the function like SerilizeAndValidate(ObjectToSerilizeAndValidate) , clearly this method / class , is doing 2 things , Serialize and Validation, clearly a violation , some time methods in a class leads to maintenance nightmare like above example of serialize and validation 说我写了像SerilizeAndValidate(ObjectToSerilizeAndValidate)这样的函数,显然这个方法/类,正在做两件事,序列化和验证,显然是一个违规行为,一些类中的方法导致维护噩梦如上面的序列化和验证示例

Yes, you are right to be concerned about this, but again, you cannot literally have methods that do one thing only. 是的,你关注这一点是正确的,但同样,你不能真正拥有只做一件事的方法。 Remember that different methods will deal with different levels of abstraction. 请记住,不同的方法将处理不同的抽象级别。 You might have a very high-level method that calls SerializeAndValidate as part of a long sequence of actions. 您可能有一个非常高级的方法,它将SerializeAndValidate称为长序列操作的一部分。 At that level of abstraction, it might be very reasonable to think of SerializeAndValidate as a single action. 在该抽象级别,将SerializeAndValidate视为单个操作可能是非常合理的。

Imagine writing a set of step-by-step instructions for an experienced user to open a file's "properties" dialogue: 想象一下,为有经验的用户编写一套分步说明,打开文件的“属性”对话框:

  • Right-click the file 右键单击该文件
  • Choose "Properties" 选择“属性”

Now imagine writing the same instructions for someone who's never used a mouse before: 现在想象一下,为以前从未使用鼠标的人写下相同的说明:

  • Position the mouse pointer over the file's icon 将鼠标指针放在文件的图标上
  • Press and release the right mouse button 按下并释放鼠标右键
  • A menu appears. 出现一个菜单。 Position the mouse pointer over the word "Properties" 将鼠标指针放在单词“属性”上
  • Press and release the left mouse button 按下并释放鼠标左键

When we write computer programs, we need to operate at both levels of abstraction. 当我们编写计算机程序时,我们需要在两个抽象层次上运行。 Or, rather, at any given time, we're operating at one level of abstraction or another, so as not to confuse ourselves. 或者,相反,在任何给定时间,我们都在一个抽象层次或另一个抽象层面上运作,以免混淆自己。 Furthermore, we rely on library code that operates at lower levels of abstraction still. 此外,我们依赖于仍在较低抽象级别运行的库代码。

Methods also allow you to comply with the "do not repeat yourself" principle (often known as "DRY"). 方法还允许您遵守“不要重复自己”的原则(通常称为“干”)。 If you need to both serialize and validate objects in many parts of your application, you'd want to have a SerializeAndValidate method to reduce duplicative code. 如果您需要在应用程序的许多部分中序列化和验证对象,则需要使用SerializeAndValidate方法来减少重复代码。 You'd be very well advised to implement the method as a simple convenience method: 建议您将该方法实现为一种简单的方便方法:

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

This allows you the convenience of calling one method, while preserving the separation of serialization logic from validation logic, which should make the program easier to maintain. 这样可以方便地调用一个方法,同时保留序列化逻辑与验证逻辑的分离,这样可以使程序更易于维护。

I don't see this as doing more than one thing. 我不认为这不仅仅是一件事。 It is just making sure your string passes a required condition. 它只是确保您的字符串通过所需的条件。

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

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