Friday, September 16, 2011

Maintenance costs versus writing better initial code

But I wonder the cost of having a poor programmer do something that has high maintenance costs but is available right away as opposed to wait for a good programmer to be available to do it.  My guess is you are still better off waiting, but I think people find themselves in this spot more than any.  They know that good programmers write code that is easier to maintain, but they feel there is an urgency to get something done and they can't find a 'good' programmer to do it now.  The compromise is, get a not so good programmer to do it and potentially make a mess and if the system lives long enough, get the good programmer to come along when they are available to make it better or fix it.

Obviously I consider myself a good programmer.  In my 12+ year career, I have spent less time maintaining a system wrote well than I have maintaining/fixing one that someone else wrote poorly.  
Early in my career, I spent most of my time maintaining code that I had written poorly.  So for the first 3-4 years, 'I' was the not so good programmer whose code I maintained.  But at some point I started getting better and I spent more time dealing with fixing other systems than ones I wrote.  My code was still not 'great' since it was difficult for me to hand off to anyone but the bugs were much lower than my first few years coding and when bugs came up, I could find and fix them more readily.
After my 6th year (or so) I started following some 'Agile' development practices.  Not 'processes'.  I used "Agile Developer" techniques geared toward making the code I wrote more easy to change and more easy to keep in a working state.  This also facilitated working with other developers more.

I started writing code that junior developers could take a run with it and I moved on to other things.  This happens a lot with "Senior" devs handing off work to "Junior" devs but not always in a manner that enables the junior devs to be productive.  I think a truly senior developer's main task is to write code that is easy for someone else to modify.  Getting it to 'work' is assumed and means little when you are supposed to me a senior software engineer.

Some senior software engineers justify the complexity in their code to "It's hard stuff."  "I'm smarter/senior so that is why I understand it and you don't."  This is bull.  More often than not though, that same senior developer subconsciously is 'protecting' their code with complexity.  If you don't want some sharp young developer to come along and show you up, make their job hard.  Hand them overly complicated code to maintain and prove you are smarter than they are.

Yes, some things by their nature are complex, but a truly good dev lead can boil it down so that someone else can be empowered by the design to be productive.  If you are 'senior' and a 'junior' dev can't maintain/modify your code it is YOUR fault 9 times out of 10.  Even if they are not necessarily very experienced or skilled.  You should be enabling them and building up their confidence with well designed code.  You should not be crushing their spirit by dropping a pile of crap in their laps and saying, "This code is about 99% done.  I just need you to plug the database in."

Monday, September 12, 2011

Two Things

I decided to use the programmatic properties file reading for a more 'sensible' solution to my last implementation:


applicationContext.groovy (via spring-grails DSL/BeanBuiler) in the src/webapp/WEB-INF directory

...
Properties properties = loadProperties(logger)
...

Properties loadProperties(logger) {
    String baseFilename = "overrides.properties"
    String defaultBaseFilename = "default.properties"
    def contextClassLoader = Thread.currentThread().getContextClassLoader()
    String defaultFilename = contextClassLoader.getResource(defaultBaseFilename).getFile()
    String overrideFileName = contextClassLoader.getResource(baseFilename)?.getFile()

    File defaultPropertyFile = new File(defaultFilename)

    Properties properties = new Properties()
    properties.load(new FileReader(defaultPropertyFile))

    if(overrideFileName) {
        File overridePropertyFile = new File(overrideFileName)
        if(overridePropertyFile.exists()) {
            logger.info "Loading overrides..."
            properties.load(new FileReader(overridePropertyFile))
        }
    }
    else {
        logger.warn "No override properties file was found, using project defaults ONLY."
    }
   
    logger.info "Properties"
    properties.each {k,v -> logger.info "$k=$v"}

    return properties
}

The throughout the 'beans' closure, I can say 'properties[property]' at load time rather than getting a proxy as the last implementation returned.  This means I can use properties to conditionally configure
beans based on environment.  It also allows a 'default.properties' file that will hopefully cover 90% of
what will be done and then the 'overrides.properties' can cover the few things that will likely be
different but can be loaded via that environment (e.g. tomcat/lib).

The other thing is I did very basic implementation with full CRUD for an EclipsePhase character tracker with a Flex front-end and a Gaelyk back-end.

http://ep-tools.appspot.com/epui.html

Slow services on app engine, but free.  Using the app engine Entity for persistence is easy but I still thing I'll look at doing it with Grails and deploying to CloudFoundry as long as it is 'cheap enough'.

Code is nothing exciting but on github.

https://github.com/twcrone/eclpsephase-character-tracker-services
https://github.com/twcrone/eclipsephase-character-tracker-ui

No guarantees that the code will stick around or stay the same as the base site.  Cool thing is...with Flex (and my skills), the back-end can change.  Not embedded in any particular environment (e.g. Gaelyk, Grails, Rails, Spring).


Wednesday, September 7, 2011

Spring Grails Bean Builder Confusion

Spent hours today trying to convert some traditional Spring XML config into more dynamic Grails Bean Builder script to allow dynamic config based on the environment that the webapp is deployed (Windows vs. non-Windows/*nix).  This was NOT a Grails project so I first had to include the dependency in the build.gradle file.

    compile "org.grails:grails-spring:1.3.7"


Here is a snippet of the Spring XML I was trying to convert:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:property-placeholder location="classpath:config.properties"/>

    <bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
        <property name="targetConnectionFactory">
            <bean class="org.apache.activemq.ActiveMQConnectionFactory">
                <property name="brokerURL" value="${jms.brokerUrl}"/>
            </bean>
        </property>
        <property name="sessionCacheSize" value="10"/>
        <property name="cacheProducers" value="false"/>
    </bean>

    <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory"><ref local="connectionFactory"/></property>
    </bean>
...
</beans>

All was okay until I tried to deal with the 'property-placeholder' for the config.properties.  I tried lots of stuff and on a whim tried this very counterintuitive thing with a Java String for the property key that looks like a Groovy String that in the BeanBuilder should be interpolated:

beans {
    xmlns context:"http://www.springframework.org/schema/context"

    context.'property-placeholder'('location':'classpath:config.properties')

    activeMqConnectionFactory(org.apache.activemq.ActiveMQConnectionFactory) {
        brokerURL = '${jms.brokerUrl}' // Yes, this is meant to be a java.lang.String
    }

    jmsFactory(org.springframework.jms.connection.CachingConnectionFactory) {
        targetConnectionFactory = activeMqConnectionFactory
    }

    jmsTemplate(org.springframework.jms.core.JmsTemplate) {
        connectionFactory = jmsFactory
    }
...
}


Yes boys and girls...


'${jms.brokerUrl}'

Major brain eff here with something that looks like it should be "${jms.brokerUrl}" with double quotes for Groovy String interpolation or perhaps even simply jms.brokerUrl like a variable attached to a dynamically generated property on the beans object.  I even tried context['jms.brokerUrl']and beans['jms.brokerUrl']to no avail.

I tried the actual solution when it occurred to me that Spring would not be doing interpolation on the ${blah} like Groovy when reading the XML.  For Spring, that means 'use this string as a key to a resource'.
Oyvay.