Pruning

Posted in Jerry Andrews on June 24th, 2009 by admin

I spent the past few hours pruning the trees along my property line–mostly across the line on the neighbor’s side, but they’ve grown in and through my fences, and developed into quite a thicket along the property line. The bushes acted as a lower story for the trees which are planted along the line, and looked quite nice; I didn’t realize what a mess they’d become. Once I started, I realized they were choking out the bases of the big trees, and had become infested with a mess of thorny vines which had bound the whole thing together into a green mass of dead limbs and vine. Now that they’re trimmed back, the trees look nicer, and the edges of my lawn are free to grow; in 2 weeks, I now realize, it will look a lot nicer than it has in the past couple of years.

In my project work, I regularly come across thickets of choked code which is hard to read and even harder to update. I fixed a bug yesterday which should’ve take an hour to fix, but took almost 12 hours, because I had to write a 2 new unit test suites, making sure to cover all the old code. That took about 10 hours; then the last 2 were spent brutally pruning and finally, fixing the bug. What’s left is small and tight, and will be a lot easier to maintain, since it has a nice suite of unit tests.
It’s easy to let the thicket grow. It’s also easy to write tests while the classes are still small, and keep them up to date as the code evolves. Then, when a class does turn into a thicket, it can be pruned quickly and with authority, because the tests are already there.

FitNesse for a Particular Purpose

Posted in Jerry Andrews on June 21st, 2009 by admin
I’ve been aware of Ward Cunningham’s “Fit” framework (http://fit.c2.com/) for some time. I’ve never actually used it, because it seemed “hard” and my business analysts had their own way of doing things.
My current project introduced me to “FitNesse” (http://fitnesse.org/), a wiki which integrates the Fit framework with wiki pages, and forced me to learn to use it for real enterprise-scale projects, both interactively and as an automated test suite to be run as part of our continuous build process.
Boy, have I been missing out; this thing rocks!
At the core, FitNesse is a wiki. It’s important to remember that, because as it’s presented in the documentation, it’s primarly a test tool. But here’s the thing: if you just type your requirements into the wiki, it more-or-less demands that you write tests, too. That is, that you express your requirements as something that the developers must test. That has two huge benefits: 1) it makes sure developers speak the same language as the requirements, and 2) it forces requirements to be testable. Because it’s a wiki, as developers and analysts come to a shared understanding of the requirements, either can easily tweak the pages to say what needs saying, and the tests to express those requirements succinctly.
As requirements and associated tests are developed in FitNesse pages, you can check them in to source control, run them regularly, and there’s no need to back-trace test to code to requirements–if the FitNesse tests run, you’ve met all the requirements they embody. It’s about the shortest distance between requirements and a quality deliverable I have ever seen, and one of the lowest overhead. Rather than checking our FitNesse pages in “at the end of an edit”, we have a scheduled job which checks in any changes at the end of every day.

The examples on the Fit and FitNesse web sites are simple; I encourage you to go there now and have a look. These are great for learning, but they don’t express the real power of the tool.
Here’s an example from my current project in all its enterprise-messy glory. This is what real enterprise application testing is about. The image below is about 2/3 of the testing page for one scenario (click the image for a full-size rendering. It’s large (about 100k, and about 3x my screen)). Most of the page sets up the test conditions. Along the way, there are tests to verify the (very complex) input data are correct; “Read Tax Rate Area”, for example, generates numbers which aren’t in any specific location–they’re summed over dozens of inputs already in the database. Any heading with a question mark is an invitation to invoke the application code to see what the results are.
Binding this page to the application code requires a “fixture”, which each developer writes. Fixtures are typically quite small. The set of fixtures which executes the tests on the page shown total 596 lines of code; it took me about a day to write, including figuring out exactly how to perform the required setup. I had to write a fixture base class which took another day, but now that I have that written, writing new complex tests will be as simple as writing this one was. This scenario, and 11 others just like it, run using the same fixture and exercises the same code as runs in production. Those 11 scenarios represent most of the edge cases in one kind of billing. There are many more; a total of around 400 scenarios and thousands of individual tests.

To run the test, you simply punch the test button in the upper right-hand corner of the page. I’ll walk through some of the results. First, the top of the page notes that 2 tests succeeded, 2 failed, 2 were ignored completely (usually as a result of failure), and 2 exceptions were thrown. Each row typically represents a test, and that’s not anything like the full population of the page, but exceptions tend to end things abruptly. Secondly, note the “Read Tax Rate Area” block, where two tests ran, and both failed. Thus, the assumptions which are built into results further down the page are proven wrong–the testers need to know this so they can revise their expected answers. One important thing to note is that the framework handled the display; all the fixture code does is respond to “getLipTaxRate()” and “getLiTaxRate()”–names derived from the associated headings–with a text string. The framework colored the cells and placed the “expected” vs. “actual” answers on the page.


Scrolling down, there’s an exception. Yes–I made a mistake in the fixture which, under the right conditions, throws an NPE. I’ll fix that in the next release. On down is a successful test.
That’s what it looks like. The fixture code is easy to write, the requirements are expressed in a way the business people understand, and there’s a man-day or less (usually far less) between describing the behavior in a FitNesse test and writing the fixture which connects the test to the functional code.
In our environment, FitNesse tests are also run automatically as part of our automated build cycle. The tests span hundreds of wiki pages. The results are consolidated into a nice punchy list with counts of successes and failures, much like the top of the first “post-run” page above. For failures, more detail is provided. The XML parsing is done by fixures already available in CruiseControl. I found excellent help for configuring our ant build (and thus our CruiseControl build) at http://www.jroller.com/njain/entry/integrating_fitnesse_with_cruisecontrol. Thanks, Naresh!
What more could you want in a requirements/code/test/document system? Go forth and experiment. You’ll be glad you did.

Measuring the Unmeasurable

Posted in Jerry Andrews on June 17th, 2009 by admin

In a previous post, I wondered how you measure yourself as a developer. The available metrics are pretty poor, overall. Consider all the ways a developer can be “good”–fast, good at translating requirements into functionality, good at the key algorithm, good at clear, concise code, good at predicting when she’ll be done with a given bit of code… on and on. How do you measure that? The short answer seems to be: you don’t. I haven’t found a single metric which addresses developer quality which is in any way objective. Then I cast back to my earlier life as an engineer–and surprise! Exactly the same situation exists there.

At the best large companies I’ve worked for — Babcock & Wilcox, GPU Nuclear, Oracle — jobs I look back on with fondness — individual performance was evaluated by senior people, and job descriptions were carefully thought-out lists of subjective performance metrics. When I was promoted from Engineer 2 to Engineer 3 at GPU Nuclear, my boss and I went over the metrics for that job to see which I hadn’t quite mastered yet, and that became my development plan. When I mastered Engineer 3, I would start on the list for Senior Engineer 1, and when my superiors felt I had mastered enough of that list, I’d be promoted again.
No such list has governed my development as a software developer, designer, and architect, except at Oracle. I’ve been promoted several times, but there were never any objective criteria against which I could say “see? I have done this”, or “boy, here’s an area I should work on”. More than once, I’ve been involved in projects where the “senior” architect, designer, or developers were among the least-accomplished on the team. This can only happen in a situation where measures of capability–even if they are evaluated subjectively–are not present.
The chief architect at Sabre Airline Solutions and I spent some time a year or two back discussing job descriptions for various programmer levels and career paths. While we didn’t discuss specifics, I now wish we had. In my career as a developer, I have seen only one set of specifics for different developer levels: the job descriptions in Oracle Consulting Services. I wish I had those descriptions now; my recollection is that they were concise, complete, and compelling. I’ll try to collect some job descriptions for developers over the next couple of months. Perhaps there’s something available that could be used to address the whole “what’s a good developer” question.

What Needs Doing

Posted in Jerry Andrews on June 14th, 2009 by admin

I have participated in more than one fiasco. A close friend (and excellent developer) friend of mine is doing so now. These are generally “successful projects” in most senses of the word, except for one key fact: they don’t deliver anything new, at a cost of several tens or even hundreds of thousands of dollars.

My personal favorite, and an instructive example, is a nine-month, 6-man replacement project for the public client of an n-tier, mission critical, customer-facing application for a very large public cash-squeezed company. I was architect for this application for several years, and I made a number of specific recommendations for it as I was leaving, including one that the client be refactored so that business logic present in the client (for good architectural reasons) was separated from the display logic. We delivered the first piece of that refactor–a display controller separate from the display code itself–and recommended that it be used for all screens, not just the ones for which we piloted it. For no reason I could understand, the architect who replaced me decided to completely replace the client–including hundreds of working screens, huge chunks of interface logic, state management code, encryption and masking code for credit-card processing, terminal interface code, etc. Knowing his management team, I’m sure the work was justified in bafflegab. The project is just wrapping up, and a cost and schedule of just 5 and 3 times (respectively) the original refactoring estimate. What problem were they trying to solve that could justify this kind of expense?
The original refactoring was proposed to address the fact that the client had become very rigid and spaghetti-bound. It was hard to understand and harder to modify, so that even small changes (and there were many of those in the queue) required weeks to make and test. All the senior developers understood that the source of the problem wasn’t the screen display code, or the hardware or server interfaces–it was the way business logic was in-lined into the screen transition code. Once that was moved out into business logic classes and properly tied into a separate screen controller, most of the problems in the client would be resolved. Such a project was difficult but was nicely bounded; we estimated a 2-man team consisting of our 2 best and most experienced developers working for 3 months could complete it. Instead it took a team of 5 working for 9 months to rewrite the entire client. Now they have a nice new front-end written in Adobe Flex–and since all the Flex coding was subcontracted, nobody on the development team can maintain the client UI. I will make a prediction: the new client will be more expensive to maintain than the old one.
I hope I’m wrong. Fortunately, I don’t work there anymore.
I see this kind of thing all the time. On my current project, a relatively junior engineer was given free reign for 3 months to refactor a chunk of functionality which runs once a year to reduce the running time from 18 hours to 3 hours. The source of the requirement was the engineer in question–not the users, not the management team. Now the code is barely readable–but it sure is fast. Of course, to make up the 3 months of developer time spent, the annual process has to run about 30 times–a process which will take between 15 and 30 years. Any changes to the process will require man-weeks of developer time to make instead of man-days. In short, there’s almost no way to justify that kind of expenditure.
So: how are these decisions made? Why do managers allow them? What could possibly justify this kind of wasted effort? And finally: why do otherwise good designers and developers allow them to happen?

Quality Developers

Posted in Jerry Andrews on May 6th, 2009 by admin

How do you know if you’re a good designer?  How do you know if you’re a good developer?

Everyone seems to recognize a good developer when they see one.  I’m not so sure, though, that we know what we’re looking at.  I submit a good developer writes code which meets the customer’s requirements, quickly, and the resulting software is easily understood by someone who is familiar with the domain–it is maintainable.  A good designer writes designs which, if implemented, meet the customer’s requirements, quickly, and which, if given to a developer, results in software with the same qualities. There are other qualities as well: ability to work well with others, the ability to explain what they’ve done; the ability to communicate with business analysts to identify and clarify requirements, the ability to estimate the time needed… there are probably others.
By what metrics do we identify good developers and designers?
The industry struggles to identify metrics for code.  There is a developing body of literature on the subject; just google “software metrics” and you’ll see what I mean. By contrast, I have never worked on a project which provided objective tools for developers to measure themselves. Since the projects I work on tend to stretch over years and cost millions of dollars, this seems like quite an oversight. (The same point can be made of technical project managers, but that’s another realm from the one in which I work.)
As a starting point, applying code metrics to a developer’s code over time might provide insights into a developer’s skill as a coder.  But what about all the other skills necessary to be a good developer?  Developers, I daresay, spend most of their time translating requirements (be they in the form of traditional requirements, tests to satisfy, or a design to be implemented) into “local design” for the code they want to write. How do we quantify that?
I’m currently working my way through this article on quality metrics: http://www.developer.com/tech/article.php/10923_3644656_1.  I’ll continue to post as I work through it.  I have a reading list; I’m hoping for insights. So far–nada.

Library Services

Posted in Jerry Andrews on April 19th, 2009 by admin
My emotional favorite: GuruLib.com. Two young people, tremendous technical skill and creativity. Not the richest site, but it’s terribly easy to use, and the enthusiasm they have for their product is palpable.  I love the clean design.  I wish there were a few more controls over layout and content, and that their search engine had all the features of LibraryThing, but wow, it just feels good to use.  It has two features I absolutely love (and I seldom love things about software): 1. I can download my library data, so it’s not captive, and 2. it goes to Amazon every night and produces a value estimate, which I then squirrel away for my insurance company.  I also really like their integration into other social network software… so much so that I broke a personal rule and authorized their application on my FaceBook page. Nice work, folks.

My technical favorite: LibraryThing.com.  Vast power at your fingertips.  Elegant integration with lots of libraries. They should license the webcam barcode scanner from GuruLib–if they had, I might never have gone looking and found GuruLib in the first place.

Not enough time spent yet: GoodReads.com.
A note on the GuruLib webcam tool: this is just an excellent piece of UI design.  It opens a small window with the current image from your webcam, with a blank beneath and a single “add” button.  You hold a book up to your webcam until the ISBN barcode fills the image. When it recognizes a barcode, it beeps, snapshots the frame, draws a scan bar across the barcode showing what it is interpreting, and holds until the image changes significantly (e.g. you move the book away), whereupon it goes back to a live webcam view. Then, if you agree that it got the right barcode value, you can click the add button and it locates your book using its user-defined search source list (Amazon, Library of Congress, and hundreds of public libraries). It is excellent primarily because of the way it manages the “conversation” with you, the user.  It doesn’t require you to do anything with your hands except handle books and click the add button.  When I use it, my mouse never moves, so I just punch the mouse button to add.  It provides great feedback: it tells you what part of the image it used, you can evaluate if the image is clean and bright enough to be accurate, and actually compare the interpreted barcode value to the value printed on the barcode itself if that isn’t enough.  It doesn’t bother you with extra notifications or weird visual tics. I didn’t even notice the switch between snapshot and live scan until I started thinking about why I like it.  It does just what you expect it to do quietly, cleanly, and efficiently.  Sweet.

Managing the books

Posted in Jerry Andrews on April 15th, 2009 by admin

I have a few thousand books.  About a thousand of them are on shelves in the house.  Over the past few weeks, I’ve been VERY slowly sorting them on the shelves so I could find what I’m looking for… and last night I finally realized I needed help doing it.

That’s what the Dewey Decimal system is for, right?
So then it occurs to me (naturally) that the web must’ve already solved this problem.  So I went looking.  And boy have they… as long as you’re near a computer, don’t mind a short wait for each search, and are willing to enter thousands of books by hand–at least partially.
The good news is there’s lots of free services which can generate a complete listing for a book, including Dewey decimal number, summary, keywords, and all the bibliographic information you could want, as well as links to purchase sites (no thanks–I already own the book) give a title fragment or ISBN number or really any basic identifying information. For a small fee, you can also buy a barcode scanner (or adapt your webcam, with a bit of ingenuity), to scan the ISBN numbers which became ubiquitous on dust covers sometime in the last decade or two, which covers maybe 50% of my library.
The bad news is that while that helps a lot, I still have to get the data into the computer somehow–and it doesn’t really solve my filing problem.
I want a solution which (a) gets me bibliographic data on all my books in searchable form, (b) doesn’t cost thousands of dollars, (c) will allow me to find what I’ve indexed. RFIDs paired with an existing on-line system seem like the natural choice.  And RFID reader can be got for as little as $50 (and as much as $1000 for a hand-held proximity unit).  Tags cost quite a bit–so much that they violate criterion (b), so that solution has to go on the shelf for now. The price is falling dramatically as manufacturers find ways to print them on labels and manufacture them without a silicon backing, though, so I’m hopeful this will be practical in another couple of years.
For now, I’m experimenting with http://www.librarything.com (my favorite so far), http://www.goodreads.com, and http://www.worldcat.org as tools for getting me enough data for good filing.  And I’m still looking for a real solution to the problem.

And now for something completely different

Posted in Jerry Andrews on March 13th, 2009 by admin

My wife’s bluetooth headset uses a non-rechargable AAAA battery.  Right.  Where do you get AAAA batteries?

Answer: ask the web; it knows everything.  And it says “inside a 9-volt battery”.
I slipped a letter opener under the bottom edge of a new 9-volt battery where the metal meets the cardboard and lifted up a corner.  Then, with a pair of pliars, I peeled off the cover.  Here’s what I found:
The batteries are held together with a bit of blue shrink-wrap, which I sliced off:
Now they come apart like an accordian.  They’re held together with spot-welded straps.
By gently pulling them apart, each battery came off with one or two bits of joining strip; gently pulling THAT off with a pair of pliers gave me 6 batteries and some scrap.
After lightly filing off the sharp corner left by pulling off the welded strap, I had 6 AAAA batteries for about $2.
:)

What Executes?

Posted in Jerry Andrews on March 1st, 2009 by admin

One problem executable design tools face when parsing and executing a design is “what do I execute”?
During the creative process, you tend to work with diagrams rather than class or object definitions. If you’re fairly messy, as I am, you may end up with an underlying model containing lots of objects, classes, and relations which don’t show up on any diagram, but which the tool created as you were adding things to the model.  You may also end up with different objects with the same name on different diagrams–class diagram 1 contains a class called “Person”, and diagram 2 contains a class called “Person” with some of the same attributes and methods as the first, but internally, the UML design tool has created two separate Person classes, not one.  How does the execution engine know which one to execute–or did the designer want both?
I want to use the “diagram” as the control.  If something shows up in an underlying model, but not in a diagram, it’s ignored by the execution engine. Oh, I want it listed somewhere when the model is parsed for execution, but I don’t want it showing up in my executing code.  I used the diagram to communicate with developers, not the hidden underlying model–so that’s what expresses my intent as a designer.
What’re the drawbacks of this approach?

Why Models Shouldn’t Be Programs

Posted in Jerry Andrews on February 25th, 2009 by admin
Here’s a great post on “why models shouldn’t replace programs”:
http://thedailywtf.com/Articles/The_Customer-Friendly_System.aspx
Look–Model Driven Architecture is pretty much ignored by practitioners.  In practice, really interesting problems modeled in detail result in models which are as daunting as those in the link above’s example.  The problem is, modeling is to clarify, not to replace, programming. Models must leave out lots of detail to be useful. This is almost the first thing Booch, Rumbaugh, and Jacobson say in “The Unified Modeling Language User Guide”–in my copy, page 6, in italics, in the center of the page: “A model is a simplification of reality”, followed by (again, centered and in italics): “We build models so that we can better understand the system we are developing”.  If the model becomes so large and complex that it doesn’t meet that goal, I submit it has failed.
So: I believe executable design tools must (a) execute the model faithfully, but (b) integrate nicely with existing languages for the detailed work.  Nobody wants to maintain a set of generated classes in synch with a model, and the model should be the application’s core.  It must not try to be the application!