solid-principlessingle-responsibility-principle

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;
    }

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

  1. 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?

  2. 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?

  3. Doesn't strictly adhering to SRP cause a lot of very small classes, which makes it difficult to keep track in bigger projects?


Solution

  • 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

    1. The calculate area is in the right place. Setters are very often bad.
    2. 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.
    3. 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.