• The Cost of Quick and Dirty Programming: Technical Debt

    Why do programmers always make such a big deal about best practices, proper object oriented design, unit testing, and the like? Chances are if you ask somebody who champions these ideas they’ll respond “it makes for higher quality software” or something along those lines. They are probably right about saying it makes for better software. Ideas such as these won’t produce “perfect software” but they definitely improve the chances of better software with easier maintenance.

    I am one of those programmers that believes that unit testing, thoroughly thought out OO design, best practices, etc. contribute to better software. But unfortunately, taking these actions does not come for free. They all take time and energy which translates into money.

    Unit testing is a great example. Writing tests for code can definitely add more time to a project. Possibly quite a bit more time. Many people, myself included, often just ignore testing and just wait for bugs to pop up before they are fixed. It is at times very difficult to find the motivation to write the unit tests and do what I know I should be doing.

    But this view is very short sighted.

    Writing unit tests, while time consuming up front, can dramatically save time, money, and energy later in a project. The reason is because they enable you to find bugs earlier when they are easier to fix which means time and money saved later. It is far easier to fix a bug early in a project soon after it is introduced than when it has been in the system for months and covered but by other layers of code.

    A concept that paints a good picture of the consequences for this quick and dirty approach is called technical debt. The idea of technical debt is related to commonly understood financial debt. It is best explained by Martin Fowler in his post on this metaphor.

    In this metaphor, doing things the quick and dirty way sets us up with a technical debt, which is similar to a financial debt. Like a financial debt, the technical debt incurs interest payments, which come in the form of the extra effort that we have to do in future development because of the quick and dirty design choice. We can choose to continue paying the interest, or we can pay down the principal by refactoring the quick and dirty design into the better design. Although it costs to pay down the principal, we gain by reduced interest payments in the future.

    Doing things quick and dirty, as us programmers often do, has consequences that we frequently ignore or thoroughly take the time to understand. Not writing unit tests or ignoring problematic software designs creates debt that can be difficult to pay down later. Allowing excessive technical debt without reason is a quick way to heavily burden a software project. It has happened to me just as I’m sure it has happened to you.

    But technical debt can sometimes be an OK thing. Sometimes software just needs to get done ASAP or sometimes it is a rarely used or temporary piece of software. In circumstances like this I believe it is ok to take on a certain amount of technical debt.

    This is something I need to remember. Software doesn’t always need to be perfect (if it even can be that). Sometimes it is far more important to just get it done. It often is very tempting to analyze and analyze and analyze in an effort to get that perfect piece of software but never actually get anything programmed. By keeping this metaphor in mind I will hopefully think through how I approach software in the future and think through the consequences of the actions I take.

    Additionally, I like the metaphor of technical debt as a way of working with non-technical users to explain the the time is needed to “do it right” the first time or to pay down the debt accumulated in other phases of the project. Most people have some kind of financial debt so this concept seems like an easy concept for people to understand.

    It also seems useful in explaining to other programmers who may be hesitant to embrace new methodologies and practices. In my work in ColdFusion, I’ve often found other programmers wondering why go through all the work some best practices like unit testing. They think it is too much work and don’t bother. But using this metaphor seems like an effective way to demonstrate the fallacy with that thought process.

    In short, before you program something, take the time to consider technical debt and whether you want to avoid it or accept some in the short term. I plan to do so and hope it will lead me to better think through my actions and consequences in the software I write

  • Getters and Setters in Scala

    In object oriented programming, getters and setters are something that most would agree have some real world benefits. Unfortunately, they can sometimes be annoying to write. They usually do not consist of a lot of code, but when you have the write the same thing over and over and over it gets old really fast. In my experience, most getters and setters are very much alike so it stands to reason that there must be a “better” way to accomplish the same result.

    In some languages there is support of some kind of “missing_method” syntax that allows the language to dynamically create getters and setters just by looking at the name of the method that doesn’t exist in the object. For example, in ColdFusion, there exists an “onMissingMethod” method that, when included, automatically executes when a method does not exist. This onMissingMethod gets passed the method name that was trying to be accessed and any arguments passed in. Then, by inspecting the method name (lets say, setAge) the method type and property can be determined. From “setAge” it can be determined that the method is a setter and that it should set the property “age”.

    Recently though I’ve done a lot of reading about and playing with Scala and I’ve found that it does things quite a bit different than ColdFusion, Java, and most other languages I’ve seen.

    As a first example, lets see an example of a basic class definition in Scala.

    class Person() {
     var name = ""
     var age = 0
    }

    At first glance you might think that this class only allows you to instantiate a person object but not anything more. But actually, once instantiated, you can set and get the properties by doing the following:

    // Instantiate a person object
    person = new Person()
    
    // Print the object's age and name properties
    println(person.age)
    println(person.name)

    To set the properties to different values you would do the following:

    // Set the properties to different values
    person.age = 34
    person.name = "Dustin Martin"

    Pretty simple so far. You might be thinking to yourself the same thing I thought when I saw an example like this: these aren’t getters and setters! And you are right, that is not what this is. This is simply retrieving the public properties directly from the object. In most languages this would be a very bad idea. What happens when you need to validate the age is in a certain range before it is set? What happens if you want to format the name in a particular way before returning it? In Java or other languages you would be in trouble right about now and probably kicking yourself for not taking the time to write getters and setters. If you wanted to switch from directly accessing the public properties to getters and setters you would either have to find some strange work-around or implement the getters and setters and change any code that access those properties directly to use the getters and setters instead.

    In Scala though, it is no big deal to directly access public properties. You could easily change to using getters and setters by making a couple simple changes to your class.

    class Person() {
     // Private age variable, renamed to _age
     private var _age = 0
     var name = ""
    
     // Getter
     def age = _age
    
     // Setter
     def age_= (value:Int):Unit = _age = value
    }

    What this code is doing is pretty simple. First, the variable “age” is renamed to “_age” and made private with the private keyword. Next, the getter is added by the line:

    def age = _age

    This code simply defines a method called “age” and returns the “_age” variable. Scala doesn’t require the return keyword but it would just have easily be written as:

    def age = return _age

    In addition to not requiring the return keyword, Scala doesn’t mandate the use of curly braces around a method body if the body consists of a single expression.

    Next, a setter had to be added to set the new private variable.

    def age_= (value:Int):Unit = _age = value

    This line is a bit more tricky but I’ll explain. First, the method name is “age_=“. The underscore is a special character in Scala and in this case, allows for a space in the method name which essentially makes the name “age =”. The parentheses and contents dictate the value and type that needs to be passed in. The “:Unit” code is equivalent to returning void. The remaining code is setting the “_age” variable to “value”. These things allow the method to be used in the same way as directly accessing the public property.

    person.age = 99

    But wait! Where are the parentheses in this supposed method call?! In Scala, parentheses are usually optional. The previous line could just as easily been written as

    person.age =(99)
    // OR
    person.age_=(99)

    As you can see, Scala has some unconventional ideas that provide a solid, well thought out, and an abbreviated syntax to access object properties.