Getters & Setters and its goodness and evilness

If you are a DZone reader, you will have read many posts about getters and setters and its evilness. Getters and setters are the response to an old Object Oriented principle which says that object’s implementation must not be exposed. On the other hand, there is also another old principle called Uniform Access Principle which says that client code should not be affected by a decision to implement an attribute as a method or field. Unfortunately, Java doesn’t follow this last principle.

Don’t Expose the Implementation

Currently, the most used IDE’s can generate the getters and setters for fields. Sometimes this doesn’t help, and developers automatically generate unnecessary getters and/or setters. This next example could be seen as a situation where generating getters and setters automatically is a bad practice:

package com.wordpress.j2eethoughts.ooPrinciples; public class Odometer{ private BigDecimal total; private BigDecimal partial; public Odometer (){ total = BigDecimal.ZERO; partial = BigDecimal.ZERO; } public BigDecimal getTotal(){ return total; } public void setTotal(BigDecimal total){ this.total = total; } public BigDecimal getPartial(){ return partial; } public void setPartial(BigDecimal partial){ this.partial = partial; } }

Now let’s explain because this is a bad practice. Maybe at a first glance, you may think that this implementations satisfies the principle of not expose the internal implementation of the object. Unfortunately, this is not true, everything is exposed. There isn’t much difference between this implementation with getters and setters and the hypothetical implementation with public fields. In addition, you can do illegal things with this implementation, as decrement the number of Kilometres of the Odometer. The unique advantage between this implementation and one with public fields is that you could attach some functionality in any function, like logging, checking permissions…

A more correct implementation for this class would be:

package com.wordpress.j2eethoughts.ooPrinciples; public class Odometer{ private BigDecimal total; private BigDecimal partial; public Odometer (){ total = BigDecimal.ZERO; partial = BigDecimal.ZERO; } public BigDecimal getTotal(){ return total; } public BigDecimal getPartial(){ return partial; } public void resetPartial(){ partial = BigDecimal.ZERO; } public void increment(BigDecimal inc){ partial.add(inc.abs()); total.add(inc.abs()); } }

This class implementation ensures that nothing wrong is done with the Odometer, Kilometres can only increase and you can’t rig the Odometer decreasing the total amount of Kilometres made.

Uniform Access Principle

As we have explained before, Java doesn’t satisfy the Uniform Access Principle, for this reason we will explain it using Scala. The client code must not be affected if the developer decides to implement an attribute as a method or as a field. For illustrating this example we will use a Circle class. There will be two different implementations for the attributes perimeter and area.

package com.wordpress.j2eethoughts.uap import Math.Pi class CircleVal (radius : Int){ val perimeter = 2 * Pi * radius val area = Pi * radius * radius } class CircleDef (radius : Int){ def perimeter = 2 * Pi * radius def area = Pi * radius * radius }

The client uses these classes exactly the same way in both implementations. The client doesn’t care if the developer had decided to implement these attributes as methods or as fields.

package com.wordpress.j2eethoughts.uap object Main { def main(args : Array[String]) : Unit = { val c1 = new CircleVal(4) println(c1.perimeter) println(c1.area) val c2 = new CircleDef(4) println(c2.perimeter) println(c2.area) } }

This post is not supposed to decide about the evilness or goodness of getters and setters, its only intention is to think about its use. So, we would be very glad if after reading this post, you think twice before ask your IDE to automatically generate the getters and setters.

Advertisements