被违反的原则是哪个?

huangapple go评论77阅读模式
英文:

Which principle is being violated?

问题

这个假设性的函数名字让人觉得不太好理解,我更擅长表达感觉。

假设我们有这个假设性的函数:

function computePowerAndPrintResult(int x){
  print(x*x);
}

函数名字中的 "And" 已经在暗示可能存在问题,而我个人通常不会编写这样的代码。
这里违反了哪个原则?是违反了单一职责原则吗?

英文:

I am not good at naming, I good at feeling.

Suppose we have this hypothetical function:

function computePowerAndPrintResult(int x){
  print(x*x);
}

It screams already in the naming of the function ("And") that something wrong here and personally I never write code like this.
Which principle is being violated here? Is it the single-responsibility principle?

答案1

得分: 3

是的。名称确实就是一个暗示。在违反“单一职责原则”的情况下,该函数负责两件事情:计算平方并打印结果。

命名也违反了良好的命名惯例:至少应该称为computeSquareAndPrintResult,因为没有指定指数的情况下,Power并没有太多意义。我个人会称其为printSquareOf,这样你可以像这样调用它printSquareOf(x),读起来非常自然。

英文:

Yes. The name is indeed a giveaway. In violation of the single responsibility principle, the function is responsible for two things: computing the square, and printing the result.

Also good naming sense is being violated: at the very least it should be called computeSquareAndPrintResult because Power without specifying the exponent doesn't make much sense. I'd personally call it printSquareOf so you can call it like printSquareOf(x), which reads very naturally.

答案2

得分: 1

不,不是这样的。单一责任是指一个类。当一个类做太多事情时,就违反了这个原则。当一个函数做太多事情时,你需要将它拆分。

现在我并不是说它不会有这个迹象。

在我看来,你需要一个类来计算功率,以及一个类来管理打印。

但是,假设我需要实现一个API,我会调用它并返回计算功率的PDF文件。我需要一个API来同时计算和打印结果。

然后,我会创建一个GetSquareValueOutput类,它将负责协调从SquareValueCalculator类获取数据,然后使用Printer类进行打印。

这个最后的GetSquareValueOutput类也可以叫做computePowerAndPrintResult,它不会有任何问题。我可能不会选择这个名称,因为它可能暗示着代码有问题,但最终只是与上下文有关的问题。

英文:

No it's not. The single responsibility refers to a class. When a class is doing too much then it is violated. When a function is doing to much though you need to break it down.

Now I'm not saying that it's not an indication that it does.

In my mind, you need a class to compute the power, and a class that will manage the printing.

BUT: Assume that I have a need to implement an API that I would call and it would return the PDF of the compute power. I would need an api that would both calculate and print the result.

I would then create the GetSquareValueOutput which would have the single responsibility to orchestrate getting the data from the SquareValueCalculator class and then print with the Printer class.

This last GetSquareValueOutput might as well be called computePowerAndPrintResult and it would not break a thing. I wouldn't choose the name as it hints at a code smell, but in the end it's just a matter of context.

答案3

得分: 1

TL;DR: 将名称更改为 printSquare。然后名称变得更短,同样准确地描述了您的操作,然而... 如果您真的担心单一职责原则,您仍然违反了它。这更多地说明了单一职责原则如何容易被过度应用,而不是这是一个糟糕的方法。

关于该名称的深入分析

computePower 有两个不好的地方:

  1. Power 是一个二元操作(X 的 Y 次方),而您并没有真正执行此操作;您将 Y 锁定为 2,而这个操作有一个常见的名称:square(平方)。

  2. compute 通常是多余的。square 已经暗示了计算正在进行。例如,看看 Java 的 AtomicIntegerBigInteger,它们有名为 add 的方法(实际上,在 BigInteger 的情况下,应该是 plus),但关键是它不是 computePlus。请注意,这取决于一些因素;例如,在 Java 中,通常以 get 开头获取属性,对于具有不相关属性的类,或者以其他方式 square 不太清晰(比如,与几何相关,所以 square 可能会被误解为指代形状而不是数学操作),那么这也是过于简化了问题。

这意味着方法名称的一部分应该是 square 而不是 computePower

然后我们有 andPrintResult 部分。在这里,Result 是多余的。除了结果,它还能打印什么呢?

您有两个选择:

  1. 此方法应该命名为 square,并应返回该值而不打印任何内容。再创建另一个方法来打印内容。
  2. and 是否是代码异味... 嗯。也许。看,您可以将此方法命名为 printSquare,这是简短、清晰的,并且不包含 and,然而,它与 computePowerAndPrintResults 一样违反了规则。

在许多方面,printSquare 是单一职责原则的明显违反,但如果您将名称更改为 reportSquare,代码将计算平方,然后将其报告给配置的(通过依赖注入注入的)“报告器输出流”,突然之间它就不再违反单一职责原则,但我们只是重新定义了一些词汇,代码保持不变。

英文:

TL;DR: Change the name to printSquare. Then the name is much shorter, is equally accurate at describing what you do, and yet... if you really want worry about the single responsibility principle, you're still breaking it. Which says more about how SRP can easily be overzealously applied, than this being a bad method.

In depth on that name

'computePower' is a bad name for two reasons:

  1. 'Power' is a binary operation (X to the Yth power) and you're not really doing that; you've locking Y to '2', and that operation has a common name too: 'square'.

  2. 'compute' is usually superfluous. square already implies that calculation is going on. Look at e.g. java's AtomicInteger or BigInteger which have methods named add (really, in the case of BI, should be plus), but the point is, it's not computePlus. Note that it depends on a few factors; for example, in java it is common to start property getters with get, in a class that has an unrelated property or otherwise square is not as clear as one would like (say, its geometrically related, so square could be misunderstood to refer to the shape instead of the mathematical operation), then this is oversimplifying matters as well.

That means that part of the method name ought to be square and not computePower.

Then we have the andPrintResult part. Here Result is superfluous. What else would it be printing, other than the result?

You have 2 options:

  1. This method should be named square and should return that value and not print anything. Make another method to print things.
  2. 'and' being a code smell is.. eh. Maybe. Look, you could name this method printSquare which is short, clear, and contains no and, and yet, it's just as much of a violation of the rule as computePowerAndPrintResults.

In many ways printSquare is a straight violation of SRP, but if you change the name to reportSquare, and the code will compute the square and then report it to the configured (injected via dependency injection for example) 'reporter output stream', all of a sudden it's not a violation of SRP, but all we did was redefine some words, the code remained the same.

huangapple
  • 本文由 发表于 2020年8月23日 17:02:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/63545181.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定