From the bad old days of J2EE to the bright idea that was Spring simplicity, Carlus Henry's career in software development has put him front-and-center for some of Java's major evolutionary shifts. In this Full Java life interview with Matt Heusser, Carlus talks about how and why he's changed his approach to Java development, then reveals the variety of tools that help him build quality software today.
Carlus Henry is a programmer's programmer. My reasoning for this claim will be revealed in the following interview -- the second one in JavaWorld's Full Java life career interviews series.
A full-circle career
Like many programmers today, Carlus started with coding BASIC on his Commodore 64, in 1989, at the age of 12. Yes, yes, that's a story we've all heard before. But after graduating from Aquinas College in 2000, with a degree in Computer Information Systems, he went to work for Americorps in Selma, Alabama. A year later he got his first job slinging code for Gordon Food Service, one of the midwest's largest wholesale food distributors.
Since then, Carlus has emerged as a leader in various corners of the worldwide Java community. He has helped lead his local Java User's Group, organized a Barcamp or two, and presented at local and regional software conferences on topics in Java programming. In 2006 he became an independent consultant. Today he still runs that consulting business while also teaching computer science (Foundations of Operating Systems) as an adjunct professor at his alma mater, Aquinas College.
You can probably guess what programming language he teaches.
I mentioned that Carlus is ambitious, but note what that doesn't mean:
- He didn't start his career working for a huge, multinational firm with a well-defined "career ladder."
- Despite his accomplishments, he hasn't pursued a management position (though he's keeping his options open). Instead, he's focused on becoming really good at what he does and building professional ladder based on his own accomplishments.
In short, Carlus has both had some success and worked hard to keep things interesting. In the small, 250,000-person job market that is Grand Rapids Michigan, he has built a good enough reputation to stay happily employed, never having to travel for gigs.
Let's find out what he has to say.
Matt Heusser: Tell us about your first exposure to Java. What other languages were you looking at? Why choose Java?
Carlus Henry: My first exposure to Java was actually at my first position at Gordon Food Service in 2000. I was hired as an entry-level programmer and immediately sent off to Java, UML, and Unix training. After the three-week training course I was more than qualified to write some really horrible code. (And yes, it was horrible; I had a chance to look at some of it recently and it was pretty bad.) At the beginning of my career, I was not exploring other languages. This was during the time when Java reigned supreme as far as the corporate market was concerned.
Watch an excerpt of Matt's interview with Carlus on YouTube.
Matt Heusser: What motivated you to start a Java user's group? What has it been like to lead a user's group?
Carlus Henry: Although I was not responsible for starting the Grand Rapids Java User Group (GRJUG), I do feel that it is an important part of the West Michigan software development community. I remember attending my first GRJUG sometime in early 2000, and I was amazed. This was during the time when companies like BEA (later acquired by Oracle) were competing for business in the area, and let me tell you, they really put on a show. There was food and a lot of experts were being brought in to discuss their products as well as other technologies.
Fast-forward a couple of years, and the GRJUG became dormant for a while. I contacted the individuals who were responsible for the GRJUG and asked them if I could take it over. They agreed and I have been chair for the past five years or so. We meet once a month, even through the summer, and we have had a very good turnout recently. This is probably due to the fact that we have had many meetings on developing software for the Android platform.
Matt Heusser: Has your perspective on Java technology changed over the years?
Carlus Henry: Yes. At the beginning of my career, I would have considered Java the magic bullet. Use it everywhere for everything. Now, I don't have that same mentality. There are a lot of great languages and frameworks out there that are better suited for different tasks. You have static and non-statically-typed languages, compiled and interpreted. Each of these languages has its place, and is useful and appropriate in different situations. Which one to use is really dependent on many factors.
I would always lean towards using a statically typed language with good IDE support for the back end of large applications. However, when it comes to the front end of applications, especially web applications, I think that many times it is appropriate to use a dynamic language calling web services for the back end.
Matt Heusser: I imagine that when you started programming you weren't doing test driven development, mock objects, dependency injection, or a host of other things that are now nearly free with most software development frameworks. How has your toolset changed over the years?
"There is nothing that gives you more security and confidence than an application that is supported by automated tests."
Carlus Henry: The phrase "coding by coincidence" comes to mind. I remember a process of coding with a certain direction and only a vague "undocumented" plan (which of course translates to no plan), which was typical before we started bringing tools like test-driven development into the equation. It was a very scary time. While I did all that I could to make sure that the applications that I wrote would work and were bug-free, there is nothing that gives you more security and confidence than an application that is supported by automated tests. Now, imagine working in a code base that you are not familiar with and being asked to add an enhancement. Without a supporting test suite, you are not going to be assured that you didn't break existing functionality. Scary, scary, scary times.
Matt Heusser: Has your coding style changed over the past few years? What new techniques are you using?
Carlus Henry: At my last customer engagement, one of the developers on the team challenged me by sharing some of his insights from Bob Martin's Clean Code (see Resources). For a while now I've been noticing applications that have abandoned the idea of object-oriented development. Too many times I have seen, and unfortunately written, code that was nothing more than a humongous "controller" with business logic. I have written classes that were several hundred lines long. That is not object-oriented development. Classes should rarely be that large, and if they are then there should be a good reason for them to be. Instead, they should be broken up into multiple classes where each one is responsible for a certain aspect of the functionality. I do make exceptions to this rule for data access objects, where SQL may be stored for retrieving information from the database.
Another technique that I have been using is to employ code generators. While I have tried to use code generators that are readily available, I have found that I am more successful with ones that I write myself. The main reason for this is because I can create a code generator that adheres to my customer's standards. Writing a code generator is extremely simple and can be a lot of fun to do. This may be one of those "tricks" that I use to achieve a lot of productivity within a limited amount of time. I have written code generators for queries, controllers, unit tests, and fixtures. They have definitely worked very well.
Using a local database has also proved to be invaluable. Too many times I have worked for organizations where the database is shared between the developers, a continuous integration build, and/or one of the testing environments. This, in my opinion, is a recipe for disaster. Having a database that you can run both your tests and application against drastically increases your productivity. With this, you don't have to worry about coordinating your own local development and testing with anyone else. You don't have to worry about "logically" sharding the data, so that no one corrupts the data that you are working with, and you don't inadvertently corrupt data that one of your team members (or even worse, your customer) may be testing with.
"Another technique that I have been using is to employ code generators. While I have tried to use code generators that are readily available, I have found that I am more successful with ones that I write myself."
Even with all of this, the absolute biggest thing that has drastically changed the way that I develop software comes from using a distributed version control system (DVCS). Most of the engagements that I have had, my customers have all used Subversion. I started becoming extremely interested in DVCS when a friend who works at SourceForge started using Git. We would get into conversations about Git, and I am sure that for a while I drove him crazy.
Finally, I happened upon
git-svn, which is the native support that Git has in order to interact with Subversion. I took the plunge and started using Git locally to interact with Subversion. I have written a series of blog posts on this topic, so I won't go into it in too much detail. However, using Git has allowed me to branch and merge multiple feature branches on my machine. I have even purposely checked-in code that doesn't compile locally on my branch, just in order to remember where I left off. It has been a lot of fun using Git, and when asked by my friends what I use for a Subversion client, I always say
Matt Heusser: What technology changes have most impacted your approach to writing software since you started coding in 2000?
Carlus Henry: I was first introduced to Spring in 2006, and have pretty much used it on every single project that I have been on since then. Since I had started my professional career in Enterprise Java, I really did not notice how complex the applications that I was developing prior to adopting Spring were. In order to adhere to the J2EE specification, and provide something as simple as remoting capabilities, where external applications could call functions on my application, I would have to create three separate Java interfaces for the business component that I wanted to expose. Spring brought a lot of great ideas, including dependency injection, declarative transactions, and a host of other tools that just made developing Java applications more simple.
Recently, I have been challenged to reexamine the Java EE specification. Much to my surprise, it has really come a long way. It now includes dependency injection, minimal-to-no XML configuration, and it's a cinch to create Java EE applications that support remoting, especially through web services. Before, Java EE 6, I would have chosen Spring to build an enterprise application, every time. Now, when considering which platform to use to build applications, I would seriously consider using Java EE 6.
A developer's toolbox: Carlus Henry
- Clean code
- Roll-your-own code generators
- A local database
- Distributed version control
Matt Heusser: We talked earlier about testing; has your approach to unit testing changed?
Carlus Henry: Over the past couple of years, I have changed my testing style a lot. After being introduced to test-driven development, I became a unit testing fanatic. This is a great skill to have. Testing your individual classes at the method level for a number of years have given me a lot more confidence in the code that I write, as well as taught me a lot about object-oriented programming. Many a times I have used object inheritance and dependency injection in order to test corner cases.
Today I am still a fan of unit tests but recently I have found them lacking in an important area -- requirements. Sure, you probably have heard the claim that unit tests are really "executable requirements." While this is true, they really only benefit the developer. There is not going to be an end-user who is going to read your source code in order to discover your "executable requirements." I believe that this attitude toward software development puts up a barrier between the developer and the customer. These days I prefer behavior-driven development to fill this gap between tests and requirements.
I believe that behavior-driven development gives the software developer the security that comes with unit tests. When combined with a tool like Cucumber it also enables the readability of requirements. Instead of only writing tests at the method and/or class level, you write tests at a functional and/or integration level.