nus-cs2030 / 2122-s2

CS2030 repository and wiki for AY 2021/2022 Sem 2
MIT License
0 stars 0 forks source link

Immutability #11

Open yongchein-o opened 2 years ago

yongchein-o commented 2 years ago

Description

Hi Prof is immutability just having a setter method that returns a new object? Shouldn't the client create a new object instead of relying on the setter method of an existing object?

Topic:

Specific Topics this question is related to (If Any)

Screenshots

Screenshots (if any) `

Geraldworks commented 2 years ago

I believe immutability is simply ensuring that your created objects do not undergo state modification.

If I remember correctly, prof discouraged the use of setter methods because they easily violate the principle of encapsulation if you forgot to tweak your code in certain areas such as:

  1. Creating a new instance for setters OR
  2. Including private and final modifiers

Hence you are right that setter methods are technically irrelevant. We should instead create a separate method that allows instancing of new objects.

But the key idea here is that there is no fixed way of doing something. Someone might decide to include a setter method that does not violate the OOP principles. It is perfectly valid. Find a style you are comfortable with to create maintainable code.

I hope this paints a better image of OOP.

CMIIW

hwkchia commented 2 years ago

One does not typically write a setter method just to set certain properties. Take for example, scaling a Circle by a certain factor. Although we can have setRadius(double r) method, it is more appropriate to have the method scale(double factor). Now we have to consider what is the return type of scale. If it's void, then we have mutable state, which is undesirable. To preserve immutability, the return type should be Circle, and hence

Circle scale(double factor) {
   return new Circle(this.centre, this.radius * factor);
}

Notice that from the client's perspective, the use of the scale method is simply circle.scale(2.0), rather than violating Tell-Don't-Ask as in circle.setRadius(circle.getRadius() * 2.0) or new Circle(circle.getCentre(), circle.getRadius() * 2.0). Also realize from the latter that relying on the client to deal with creating immutable objects via new is too cumbersome.