英文:
Do getter and setter methods violate the Single Responsibilty Principle
问题
class Rectangle {
private int width;
private int height;
public Rectangle(int width, int height) {
this.width = width;
this.height = height;
}
public void setWidth(int width){
this.width = this.width;
}
public void setHeight(int height){
this.width = width;
}
public int calculateArea() {
return width * height;
}
}
这个类有三个主要职责:
- 表示一个矩形。
- 提供设置宽度和高度的方法。
- 计算矩形的面积。
问题
-
这可以被视为处理不同与矩形相关的职责,还是实际上违反了单一职责原则(SRP)?如果是的话,以什么方式,是只有 calculateArea 方法违反了 SRP,还是设置器/获取器也违反了 SRP?
-
SRP 是否必须始终遵循,还是更像一个指导方针,尽量考虑,但如果不完全符合也可以接受?
-
严格遵循 SRP 是否会导致许多非常小的类,这使得在更大的项目中难以跟踪?
英文:
class Rectangle {
private int width;
private int height;
public Rectangle(int width, int height) {
this.width = width;
this.height = height;
}
public void setWidth(int width){
this.width = this.width;
}
public void setHeight(int height){
this.width = width;
}
public int calculateArea() {
return width * height;
}
Does this class adhere to the single responsibility principle? From what I understand the SRP states that a class should have only one reason to change. I've read that a good rule of thumb for the SRP is, that if you state the responsibility of your class and you can do that without using the word AND then your class is fine.
However this class has the responsibility of representing a rectangle AND providing methods for setting the width&height AND calculate the Area of the rectangle.
Questions
-
Can this be seen as all the same responsibility of just handling different rectangle related things or does this code actually violate SRP? If so in what way, is it just the calculateArea method that violates the SRP or do the setters/getters also violate SRP?
-
Also is the SRP something that must always be followed, or is it more a guideline that should be considered as much as possible, but if it doesn't fully check out thats alright as well?
-
Doesn't strictly adhering to SRP cause a lot of very small classes, which makes it difficult to keep track in bigger projects?
答案1
得分: 1
我会小心地处理SRP,因为Bob Martin介绍的方式在你直接看它时并没有太多意义。只要正确抽象化并且责任是内聚的,一个类有很多变化原因是完全可以的。此外,好的设计师通常提到一个类通常有大约2-3个责任。关于设计的一本好书是《Object Design: Roles, Responsibilities, and Collaborations》,虽然已经20年了,但其中的概念仍然百分之百相关。我还建议观看Kevlin Hennely关于拆解SOLID原则的演讲。
特别是在上面的示例中,设置器的问题在于没有验证值是否正确。如果我将宽度设置为0或负数会怎么样?这个示例很简单,已经存在一些问题。如果一个类有更多的属性,验证类始终一致可能会变得非常复杂。
关于你的问题:
1)计算面积放在了正确的地方。设置器往往不太好。
2)再次强调,Uncle Bob的SRP并没有太多意义。重要的是定义一个类有哪些责任,并在不断扩展这些类时保持清醒,知道什么应该放在其中,什么应该放在其他地方。还要在重构和提取责任时保持敏感。
3)有很多小类不是问题。问题在于能否轻松地以一种简单的方式全面了解系统。很多小类可能有助于或妨碍这一点。
英文:
I would be careful with SRP as Bob Martin introduces it as it doens't make much sense when you look straight at it. It's perfectly fine to have a class that has many reasons for change as long as they are abstracted correctly and are those responsibilities are cohesive. To add to this, good designers usually mention that a class usually have around 2-3 responsibilites. A good book to read on design is Object Design: Roles, Responsibilities, and Collaborations, it's 20 years old but the concepts are still 100% relevant. I would also suggest to watch Kevlin Hennely presentation(s) on deconstructing SOLID.
The problem with setters in particular as in the example above is that nothing is validating that the values are correct. What if I set the width as 0 or negative? This example is trivial and already poses some issues. If you have a class with a few more attributes, validating that the class is always consistent might become quite complex.
about your questions
- The calculate area is in the right place. Setters are very often bad.
- Again, SRP from Uncle Bob makes no sense. It's important to define what responsibilities a class has and be concious as one is growing those classes and have a feeling of what goes in and what should go somewhere else. And also when refactor and extract a responsibility.
- A lot of small classes is not a problem. The problem is the ability to have a good overview of the system in an easy way. A lot of small classes might help or hinder this.
答案2
得分: 0
我认为这是对单一职责原则过于严格的解释。这个类存储了矩形的尺寸,它们是可变的可能不太重要 - 这只是Java的特性。这个类唯一的“真正”功能是计算矩形的面积,它需要改变的唯一原因是如果你发明了一种不同的数学类型来找到矩形的面积。
英文:
I think this is an overly strict interpretation of the single responsibility principle. This class stores the dimensions of a rectangle and the fact that they're mutable is probably inconsequential - that's just Java for you. The only "real" functionality this class has is to calculate the rectangle's area, and the only reason for it to change is if you invent a new type of math that has a different way of finding a rectangle's area.
答案3
得分: 0
我不知道Bob Martin本人是否曾经说过,“不使用AND这个词”。这种(过度)简化的问题在于,我可以通过以不同的抽象层次来描述任何类,无论是否使用了AND这个词;因此,我不认为这种表述特别有帮助。
> 这是否可以被视为处理不同与矩形相关的事情的相同责任...
是的。
> ...或者这段代码实际上违反了SRP吗?
没有。
> 另外,SRP是否必须始终遵循...
我总是很好奇人们在提出这种问题时期待听到什么样的答案。他们是否期望听到“是的,这是一项严格的法律,绝不能违反,否则软件警察会把你锁起来”的答案?当然,对这种类型的问题,你将收到的唯一答案是“根据判断违反这一模式时需要”。但我怀疑提问者早就知道这一点,只是在寻求得到他们一直想要的许可。
> 严格遵循SRP是否会导致很多非常小的类...
《Clean Code》(第139页)
> 许多开发人员担心,大量小型、单一用途的类会使理解整体情况变得更加困难。他们担心必须从一个类导航到另一个类,以弄清楚如何完成更大的工作块。
>
> 但是,一个拥有许多小类的系统与一个拥有少数大类的系统一样多的组件。在有少数大类的系统中同样需要学习。所以问题是:你想要将你的工具组织成具有许多小抽屉的工具箱,每个抽屉都包含定义明确且有标签的组件吗?还是你只想要几个抽屉,将所有东西都扔进去?
英文:
I'm not aware that Bob Martin himself has said, "without using the word AND." The problem with that (over-) simplification is I can describe any class with or without the word AND by describing it at different levels of abstraction; so I don't find that particular phrasing helpful.
> Can this be seen as all the same responsibility of just handling different rectangle related things...
Yes.
> ...or does this code actually violate SRP?
No.
> Also is the SRP something that must always be followed...
I'm always curious what sort of answer people imagine when asking a question like this. Do they expect to hear yes, this is an ironclad law that must never be broken else the software police will lock you away? Of course the only answer you will ever receive to this type of question is, use your judgement and violate the pattern when necessary. But I suspect the questioners already know this and are merely seeking permission to do what they wanted all along.
> Doesn't strictly adhering to SRP cause a lot of very small classes...
Clean Code (page 139)
> Many developers fear that a large number of small, single-purpose
classes makes it more difficult to understand the bigger picture. They are concerned that
they must navigate from class to class in order to figure out how a larger piece of work gets
accomplished.
>
>However, a system with many small classes has no more moving parts than a system
with a few large classes. There is just as much to learn in the system with a few large
classes. So the question is: Do you want your tools organized into toolboxes with many
small drawers each containing well-defined and well-labeled components? Or do you want
a few drawers that you just toss everything into?
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论