Object Oriented Programming

As many GIS users become GIS developers, one of the harder ideas to fully digest is object oriented programming (OOP). This section is not going to "teach" you the details of OOP, but I will go over a few issues I've seen when people more from procedural coding to writing actual OOP code of their own.

What is OOP?

Here's a good definition from Wikipedia...

Object-oriented programming may be seen as comprising a collection of cooperating objects, as opposed to a traditional view in which a program may be seen as a collection of functions, or simply as a list of instructions to the computer. In OOP, each object is capable of receiving messages, processing data, and sending messages to other objects. Each object can be viewed as an independent little machine with a distinct role or responsibility.

There is no magic to OOP, it is just a different way of thinking about and writing code. In many cases you may actually write more lines of code, but the benefits far out weigh this extra effort.

Nomenclature: Classes vs. Objects

This is a question I always ask in interviews, and the answer is simple: an Object is an instance of a Class. What we write as developers are classes. What exists in memory while the software is running are objects. Know it. Own it. Be it.

Procedural Programming with Objects

This is perhaps the most common first phase that most developers go through. Essentially, you are writing a program using an API that is object oriented, but the code you write is not. The result is that you still end up writing procedural code in "Big Ugly Functions". While it's common overall, I think it's especially prevalent in GIS, and at some level it flows from the fact that many times we are automating a series of tasks. When translating the series of tasks into code, the tendancy is to write this out in one big function. While this can work (many examples show this sort of thing), it does have some problems - primarily when things get complex. Maintaining this complex code soup is very difficult, and as you may have guessed, using objects can really help out.

Rolling Your Own

Although it's very hard to convert a procedural application to an oject oriented application, it is relatively easy to start thinking in objects (A good book to help out is Object Thinking by David West).

When starting a project, make a list of the "things" you are working with. This is sometimes referred to as creating the "Domain Model". Despite being very ephemeral, software tends to deal with things in the real world, so locating your classes should be relatively easy. Once you have this list, start thinking about what you need to know about them. The "need to know" part is important because there could be hundreds of properties of the object (i.e. a car), but since we are trying to keep things simple, we only want the properties that our software needs to know about. Next, we need to determine what that object can do. This is also known as defining the methods. Once we have all of these mapped out, we're well on our way to an object oriented solution - we just need to code it!

Encapsulation - Hiding the Details

This is where OOP really makes a difference. Back in the old procedural code, where everything was in one big long function, everything "knew" the details of everything else. If you needed to change how one part of that function worked, you'd likely need to make a lot of changes all over the code.

When we are working with classes, the details are hidden (or encapsulated) within the class, and the only details its clients need to know about are it's properties and methods. How the method is implemented inside the class is of no concern to the class calling the method - so long as the method returns the correct data. If a bug is found, the developer can go back and make a change inside a method, and it will have no effect on the classes which call it. This makes maintenance much simpler.

Writing Maintainable Code

If you are writing anything beyond a very simple tool for yourself, chances are you are going to need to update the code at some time in the future, likely well after you have forgotten all the details which seemed so obvious when you wrote it. Part of the solution lies in creating and maintaing design documentation, but there are also things you can do in the code itself to make things easier. Here are a few tips for writing code you can maintain without losing your mind.

  • Keep methods short and focused
  • Use understandable method names
  • Use readable variable names
  • Comment your code
  • Comment your code
  • Comment your code

Side Effects

Unlike special effects in movies, these are bad things to encounter. A "Side Effect" occurs when something effects the internal implementation of a method, in a way which is not expected. The end result is code which may "look" correct, but acts incorrectly in certain situations. A very common way to end up with a mess of side effects is through the mis-use of "global" variables. In this case, a the variable gets set in one place, and then changed in another, and finally used in some other location - all of which is not apparent to the developer. These sort of problems are really tough to track down.

The best way to avoid them is to not use globals if you don't need them.