Saturday, June 23, 2007

How not to teach programming: Getter and Setter Methods

I am far from the first person to rant about "Getter and Setter" methods. (some have even said they are evil).. but it's been awhile since anyone has posted a new diatribe on the subject, so what the heck:

Introducing "Getters and Setters" to neophyte programmers can be harmful unless it's done right... Yes, I said harmful.

Becoming a good programmer requires internalizing the concepts of programming... One must learn to think like a good programmer and that requires being able to truly grok "why" the concepts were developed, not just blindly adopt or obey them like religious dogma.

"Getters and Setters" are an artifact of the Encapsulation concept.
The Encapsulation concept, simply put, is to hide details that do not have to be exposed. Keep secrets: Do not tell anyone about the internal details of a program unless they absolutely need to know those details.

The big "why" of the Encapsulation concept is to preserve flexibility. People who use a program can only truly rely on the published details about that program. Keeping internal implementation details private allows the programmer to change those details in the future, as long as those changes do not impact the previously published details about the program.

I could easily launch into a discussion on the evil caused by programmers who rely on unpublished side-effects, but I will resist that urge (for now).

So back to "Getters and Setters"; Where's the potential for harm?

Consider the following Java class definition:



public class Dog
{
private int fleas;
public int getFleas()
{
return fleas;
}
public void setFleas( int howMany )
{
fleas=howMany;
}
}


This example is a pretty standard introduction to "Getter and Setters"... and in fact I copied it (with modifications to protect the guilty) from a very popular Java book. Nothing fancy, and certainly nothing that could possibly be harmful... unless of course you are actually trying to learn how to program.
This example focuses on language features and could be interpreted to read something like this:
"All data elements of a class should be private, and for each data element you should write one method to set the value of the data element and another method to get the value of the data element."
Sounds more like a rule than an explanation... and the neophyte will end up thinking that they have to expose every data element via a Getter and Setter. So much for Encapsulation.
Learning to Program is not just about learning rules.
Maybe it's a stretch to cause this example harmful... but it demonstrates a rule rather than a concept. This example shows "How"... but there is no clue of "Why?". What is the underlying principal we are trying to teach?
The following change to the method "setFleas" makes this example much better:


public class Dog
{
private int fleas;
public int getFleas()
{
return fleas;
}
public void setFleas( int howMany )
{
if(howMany >=0){fleas = howMany;}
}
}

Minor change, but now we have supplied a bit of the "Why?".

If all of data elements of a class are made private, then you can insure that checks can be run before anyone changes the value of any data element.
This isn't the only reason to encapsulate data, and it may not even be the most important reason to encapsulate data, but for an aspiring programmer it's a very important principal to learn:
If you don't check input parameters before using them, your program can get very messed up ("My dog has -3 fleas!"). The use of "Getters and Setters" is one way to guarantee that checks will be run before data values are changed.
As new programmers progress in experience, they'll come to appreciate the other benefits of using "Getters and Setters": Advanced concepts don't make sense unless you already understand the simpler underlying concepts.
If I am right, and teaching concepts is more important than teaching rules, then the obvious question has to be asked:
"What programming concepts should be taught first?"
I'll have to give that one a bit more thought.... What do you think?

No comments:

Post a Comment