Tuesday, February 10, 2009

The Missing Quality Metric

I knew there was a quality metric I was missing in the code review process. I have finally found it...

Much more descriptive of really code issues than just number of changes, since changes can include silly things like a brace going on the wrong line. The only down-side is that it may encourage dragging out code reviews in an effort to artificially reduce WTFs per minute. I guess nothing is perfect.

Monday, February 2, 2009

No Wonder Enterprise Software Sucks^H^H^H^H^H Is Low Quality

I am currently developing software for an IT group. This software is for the company's customers to manage their purchases, essentially. The software originally came into being in the early Nineties (using *shudder* PowerBuilder) and has been developed continually for 15 years. It is a big piece of software.

Like many enterprise applications, this one consists mostly of pages of data (lots and lots of grids) that can be interacted with in various ways, possibly leading to new screens with new grids, and so on. Given the current PowerBuilder interface is a desktop application (accessed via Citrix), the expectation is a rich, desktop-like experience.

So the company decides to bring the application into the 21st century. It is being re-written using web technologies using Java and Flex. Of course, these are the umbrella technologies; sitting underneath those umbrellas are Spring, iBatis, JUnit, JMS, LiveCycle Data Services, Anvil, and, of course, hundreds of database tables and possibly thousands of stored procedures.

These technologies lead to all kinds of architectural goodness: strong model-view-controller architecture, loose coupling between classes, separation of SQL from application logic, N-tier deployment, and abstraction at every turn. Architecturally, it is a marvel!

But for all the marvelous architecture, what does it take to actually understand a component of the system. From top-to-bottom:
  1. Find the Flex file that defines the component. Note that this may be either an MXML file or an ActionScript file. To get to the actual component you want, you may have to iterate multiple times here. Grok the UI code.
  2. Identify the ActionScript service, data objects, and parameter classes being used. Identify the server destination for the ActionScript service.
  3. Find the destination in the remoting XML configuration file (comparing string IDs). From that, I can find the name of my Spring bean.
  4. Find the Spring bean in my Spring XML configuration file (again, comparing string IDs). From this, I can find my Java service. Heaven help me if there is AOP involved that affects my code...
  5. Open the Java service. Now I have my business logic, but I may still need to find my persistence code, so now I can open my DAO.
  6. For any given method, find the iBatis IDs for the actual query being run. Luckily, our convention is the DAO and the iBatis XML file sit next to the Java service, or it would be a grep to find the actual file.
  7. Find the iBatis node in my iBatis XML file (again, comparing string IDs). Hope I'm not looking at a stored procedure...
  8. If I'm looking at a stored procedure, go to the RDBMS, open the development tool for it, and look at the procedure.
Once I understand the structure, I can limit this to only four places: MXML/ActionScript, Java, iBatis, and RDBMS. Of course, at runtime, I have to understand how data and flow control is being transferred between these.

It is too complex. I'm not a great programmer, but I am good at understanding context; yet I have a difficult time following this context. For the programmers who are on the bottom half of the bell curve, it must be impossible.

My point is not to rail to Flex and Java. Honestly, it wouldn't look a whole lot different using AJAX and Python (assuming use of an ORM and framework like Django). My point is that the architectural complexity of these applications inhibit a person's understanding of the code. Reducing the architectural complexity increases complexity in other areas (such as increasing the number of responsibilities a piece of code has), so I don't believe it is just a case of over-architecting.

When I compare the "fun" level in this, versus the fun level of the applications I was coding 15 years ago, I understand why my job isn't as enjoyable. The real danger, as I see it, is that (especially in many IT shops where the average developer is...well...average) we've overspent our complexity budget. Without actually doing anything, applications are becoming too complex to understand, build, and maintain.

My experience is that most developers give up trying to understand and just do things by convention. Look to a working sample; see how that was done; copy, paste, and change the body of some method. There may be one or two people who really grok the whole project, who are always called in on the challenging problems. The remainder of the work is done by faith alone.

As a result, is it any wonder that enterprise software sucks is low quality? More importantly, is there a better way?