Friday, December 11, 2009

Introducing SEMAT

I'm trained as a nuclear and mechanical engineer. In those disciplines, there's an underlying body of knowledge and practice for design and implementation, based on a couple hundred years of experimentation and data analysis, on what works and what doesn't, and why.

Software "engineering" as it is practiced where I usually have worked, seems to be 75% gut feel and 20% anecdotal experience, with the remaining 5% subject to real analysis. I am committed to bringing at least some of the discipline of field engineering (those parts I understand well, and can adapt) to the practice of producing software.

A group of the leading lights in methodology and architecture have come together to form SEMAT -- an acronym of "Software Engineering Method and Theory", with the goal to "refound software engineering based on a solid theory, proven principles, and best practices". It would sound like so much smoke, but consider some of the signatories:

Scott Ambler
Barry Boehm
Bill Curtis
James Odell
Ivar Jacobson
Erich Gamma

The list is quite long, and luminous.

I suggest you go have a look: http://www.semat.org. I'm looking forward to finding out what Scott Ambler and Ivar Jacobson can agree on.

Wednesday, October 7, 2009

BigDecimal

Whenever you're working with money in Java, you should be using BigDecimal. There are other applications, but far and away the most common is monetary calculations. The biggest reason is accuracy: floating point values (stored using IEEE standard 754) can't represent common decimal amounts. For that, you need actual arbitrary precision math--the same kind you learned in grade school. That's what BigDecimal provides. Yes, the operations are clumsy-looking and require a lot of typing. Wouldn't you want your bank or your tax office to have full control over the precision of the values they use to calculate your interest or taxes? You owe it to your users to provide the same precision.

Sunday, October 4, 2009

Design Constraints

Last night a bunch of us discussed the lines between architecture, design, and implementation.

I started with a working definition John Prentice gave me--heavily paraphrased, from memory: architecture is "enough design that it's clear the system requirements can be met", and design is "enough design that the path code will follow is clear". Bryan Helm suggested that architecture should also constrain design so that "good design choices will be the natural ones; bad design choices will tend to be excluded", theory being that architects tend to be senior designers as well.

There's a lot of good discussion of "what it is" on the web; I've provided some links at the end for articles I found particularly illuminating and useful.

Within the context of executable design, the group of us agreed we'd all been dealt horrible or irrelevant architectures and designs, and one hallmark of a good architecture, and also a good design, is that you could rough out code that followed the architecture, and it would execute as expected. Similarly, you could implement the design exactly, and it would execute as expected. In both cases, obviously, the system would be grossly incomplete--but the specification at the design level would be complete enough that all the functions required of the system were stubbed out and ready for detailed implementation.

I'm not sure the distinction between architecture and design is important from the point of view of a set of executable design tools. I think architecture should constrain design, and design should constrain construction. Given the way code is actually constructed, the architectural description and the design description must be maintained as the software is developed. What better way to do that than making key portions of these descriptions the armatures upon which code is developed? Code generation isn't the way to go, because you have to keep round-tripping, and you lose the abstraction provided in the design level.

The only way I can see to allow the design to constrain the construction is to use the design itself as the runtime environment for the final code. In the Java and .NET worlds, this means custom class loaders sitting between the developed code and the design, verifying conformance to the design and allowing the design to execute directly if code hasn't been provided to implement it. In this way, you can actually test the design as it is developed, in the same way you test code as it is developed: by running it.

There are many good articles; here's a jumping off point:

http://www.ibm.com/developerworks/rational/library/feb06/eeles/
http://www.bredemeyer.com/whatis.htm
http://www.itarchitect.co.uk/articles/display.asp?id=358

Sunday, September 20, 2009

Agile, but...

I've heard a lot about the poor effects of "not doing Agile"--that is, doing Agile, but...

These practitioners have a set of expectations around both process and performance. The problem I have is a huge lack of comparative data. When a team is delivering software, it's the rare business that's willing to risk productivity for an experiment to answer questions like "if they can produce x per week under process y, does x decrease if we drop agile practice 'z'?".

When I joined my current project, we were being managed in a barely-recognizable devolvement from scrum. We stopped doing stand-up meetings daily about 4 months ago; we stopped doing status meetings every other day about 8 weeks ago.

Is that negative stuff? I don't have any data either way, but I don't think so. In fact, I think we could argue that we are using exactly the agile things this team needs and can use effectively:

I delivered a formal design document about 2 weeks ago, just in time to start coding for this release cycle. We don't do much formal design, though; we mostly work from a domain model, process specifications, and FitNesse tests. Sometimes, though, you need words-in-a-row and UML diagrams.

We went into code freeze last Friday, limiting check-ins to bug fixes and test fixtures. The following Monday we received several new requirements. Since code freeze, there have been updates to something like 9 process specs. Most, if not all, of those changes will be in the release. We'll probably be in code freeze for two or three weeks, which is a lot in a six-week cycle. We're treating the new requirements as bugs, and to be fair, they're about the size you'd expect from a functionality bug.

We're delivering new functionality at maybe three times the rate of most projects I've been associated with, and at probably 6 times the rate of a typical project in this organization. It's pretty high quality stuff, too, in an environment with hideously complex business rules and very high cost for failure in implementing those rules. Frankly, I'm pretty happy about that.

Here's what we've got that works:

1. very senior, very fast developers. (Plug: if they're from Gorilla Logic, as I am, they couldn't be anything else, as that's a primary focus of Gorilla Logic's hiring practice.)

2. dead quiet when it's time to concentrate. I have a private office. I'm not physically in the same state as the users. In fact, I'm two time zones away. When it's time to crank out well-thought-out results, nothing can beat quiet. (For experimental data on this topic and other key contributors to developer productivity, read "Peopleware" by DeMarco and Lister.)

3. good access to the team when it's time to talk. We have web conferencing, IM, telephones, and desktop video conferencing when we need it.

4. requirements people who aren't bound by the need to generate a document to get the requirements to us, who are highly accessible, and who know the domain quite well.

5. management who understands the importance of getting it right, and respects the professional opinions of the team.

The release will probably slip a week. When we're done, it'll be pretty much what they needed, rather than arbitrarily "what we had working on the release date". We might deliver faster with a different management style, but I wouldn't bet my next paycheck on that. If the problem domain was simple enough to allow for stable requirements, they might not need the software in the first place.

That's agile enough for me.

Wednesday, September 16, 2009

"Really Good Programmers"

A young designer/developer/businessman I respect and admire twittered the following today:

"Really good ruby programmers can write code that is so clever that no one less talented than them has a hope of understanding it."

He really should know better.

Really good programmers can, indeed, write code so clever that no one less talented than themselves has any hope of understanding it--but they never do. That's the sort of thing really talented coders do before they become really good programmers. And then, in the code review, their peers tell them to take out the clever bit of code and make it maintainable, thereby vastly improving the code.

A decent piece of software has a lifetime measured in tens of years. During that time, it's likely to be looked at a dozen times for new features, bug fixes, and efficiency updates--not to mention the occasional port. If it took a day to write it initially, it'll probably spend many times that under someone's lens while it's in the maintenance phase. Taking 12 hours to write clear, comprehensible code instead of 8 hours to do something clever will save time in the long run. Is it always worth the extra time? No--but it is often enough that I try to do it every single time I code something.

Strange clever code is fun to write. I write a little self-modifying routine one time, both to prove I could do it, and to solve a timing issue--I counted op-codes and found I could squeeze pattern recognition between bytes on a 19.2kbps serial connection by making the polling routine self-modifying. Nowadays I'd comment it like crazy, and advise that it be removed as soon as CPU speeds increased enough to do so. Back then I wasn't a good enough programmer to know I needed to do that. Hadn't looked at enough of my own code, incomprehensible after 5 years of "rest", to know it was important to do so.

So Jon: educate that Ruby programmer of yours. Someday he'll thank you for it. All your maintenance guys will thank you for it, and you won't have to wait for that.

Wednesday, September 9, 2009

architecture by accident

I’ve been on a number of projects with a common problem set:

  • architecture is deteriorating with time, and was never strong to begin with
  • there is no architect or designer with project-wide authority
  • nobody views this as a problem–including the development team
  • time to add a feature is increasing
  • quality issues continually surface as new features affect older ones


The introduction to Booch/Rumbaugh/Jacobson "The Unified Modeling Language User Guide" makes the case for design modeling thusly:

"If you want to build a dog house, you can pretty much start with a pile of lumber, some nails, and a few basic tools...

"If you want to build a house for your family, you can start with a pile of lumber, some nails, and a few basic tools, but it's going to take you a lot longer, and your family will certainly be more demanding than the dog. ...

"If you want to build a high-rise office building, it would be infinitely stupid for you to start with a big pile of lumber, some nails, and a few basic tools. ... You will want to do extensive planning, because the cost of failure is high. ...

"Curiously, a lot of software development organizations start out by wanting to build high rises but approach the problem as if they were knocking out a dog house."

(The full text is entertaining; go forth and read the whole thing.)

As a developer, there are a couple of approaches I use to at least try to address this:

  • When adding new features myself, try to talk with everyone with code touching mine. Often there is a conceptual design in each area's designer's mind--there just is no globally-available expression of it.
  • I document my own designs with diagrams and written discussion, which I pass around for comment. I try to include global information about the global concept objects I touch. This has the effect of (often) flushing out different views of the responsibilities and limitations of key objects.
  • I transfer design information into javadoc, so the next developer can see it as (s)he codes.


Design is key to success in anything but the smallest projects. I use "success" very carefully here; some more recommended reading:

http://thedailywtf.com/Articles/What_Could_Possibly_Be_Worse_Than_Failure_0×3f_.aspx
"When an enterprise software application is deployed to production, it’s almost universally considered to be a success. In most other industries, equating completion and success would be ludicrous. After all, few in the construction industry would deem a two-year-old house with a leaky roof and a shifting foundation anything but a disaster — and an outright liability.

"Yet, had the VCF system gone live, almost everyone involved — from the business analysts to the programmers to the project managers — would have called their work a success. Even after the code devolved into an unsustainable mess, many would still refuse to admit that they had failed. The result is a cycle of failure, as dev shops refuse to recognize and correct issues that plague their projects."

Wednesday, July 15, 2009

FlexMonkey: test automation for Adobe Flex

I'm a real fan of automated testing. I really don't understand the idea of teams of people driving a UI as a way of regression testing, though there are certainly a lot of major products out there which use exactly that method to test. I think one big reason for that is that user interfaces which aren't written in HTML are notoriously hard to regression test.

A lot of what we do at Gorilla Logic is Flex atop Java. As a result of that, we had to find a way to regression test Flex user interfaces; it's not really practical for an agile team to survive without automated regression testing. Enter FlexMonkey. FlexMonkey was developed and offered to the community in open source as THE way to do regression testing for Flex, and having seen it in action, I have to say I'm really impressed. It's easy to get started with, easy to use, and easy to fully automate. The documentation is enterprise-grade, and best of all, it's free. It took me about half an hour to get it running and automated under ant, and I've never coded in Flex.

So go check it out: FlexMonkey 1.0 released in Google Code (open source) yesterday. http://flexmonkey.gorillalogic.com/gl/stuff.flexmonkey.html.

Here's a bit more about Flex and what we do at Gorilla Logic: http://www.gorillalogic.com/what.development.services.flex.html.

Sunday, July 12, 2009

Conversations With QA Using FitNesse

My current project's business rules are very complex--and the calculations often end up multiplying very small number by very large ones, or by taking ratios of numbers which aren't easily-calculated using Excel. Since my clients are mostly accountants, showing them how Excel doesn't always produce the right results doesn't really help, because (a) they rely on Excel daily, and feel comfortable with it, and (b) they don't really have an alternative.

The QA team and the users they represent have become familiar with FitNesse (http://www.fitnesse.org), and trust it. We have developed standards for presenting numerical results (10 decimal places, truncated from 17) which allow the tests to reliably reproduce the same results, even if minor details of the underlying calculations change (e.g. add values first, then multiply by rates, versus multiplying each value by a rate, then adding the results). There are two areas in which we still have trouble communicating with QA and the users: date arithmetic, and ratios of very large to very small numbers (e.g. 10^8 over 0.0011). The latter problem is complicated by the fact that in the IEEE 754 standard, which is what Excel uses to store numbers, there is no exact representation of numbers which appear in our calculations a lot, such as 0.1.

One neat feature of the FitNesse column fixture is that if the user doesn't put any information into a cell, and yet your fixture code provides a result for that cell, the result is displayed in the cell "without comment" by the Fit framework. What I did for our QA team is create a fixture which performs various calculations for them, based on inputs they provide. Here's an example of part of the fixture as users would see it:



Now they simply punch the "test" button, and here's the result:



The code to do this is shown below. FitNesse cell content is text, so you can place anything you want in a cell--I have taken advantage of this to provide more than just numerical results. The fixture code for these 4 columns is shown below, though I have removed some details of formatting and BigDecimal arithmetic to clarify how it works. I haven't included the laborious date calculations routines; think of it as an exercise. ;)


public Date date=null; // receives the date from the FitNesse web page

// as each tax year is calculated, its associated date is stored here,
// so we can refer to the list in subsequent methods.
private List dates=new ArrayList();

public String taxYear() {
dates.add(date); // for other calculations, not this one.

Format formatter = new SimpleDateFormat("yyyy");
Calendar cal = new GregorianCalendar();
cal.setTime(date);
int month = cal.get(Calendar.MONTH);

// If the date is after June 30 use the given year, otherwise year - 1
if(month > Calendar.JUNE)
return formatter.format(cal.get(Calendar.YEAR) + 1);
else
return formatter.format(cal.get(Calendar.YEAR));
}

public String fromTaxYearStart() {
if (date==null) return "";

Date start = getFirstDayofTaxYear(date);
int delta = daysBetween(start, date);
int total = daysBetween(start, getLastDayofTaxYear(date));
return delta+" (/"+total+" = "+
(new BigDecimal(delta).divide(
new BigDecimal(total)).toPlainString()+")";
}

public String fromPreviousInclusive()
{
if (dates.size()==1 || date==null)
return null;
return daysBetween(dates.size()-2, date);
}

public String fromFirstInclusive()
{
if (dates.size()==0)
return null;
return daysBetween(0,date);
}



With these tools, it is now possible to have a conversation with QA in which we discuss the input values, rather than the validity of the calculations. It remains to be seen how effective they'll be, but I have hopes.

Wednesday, June 24, 2009

Pruning

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.

Sunday, June 21, 2009

FitNesse for a Particular Purpose

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.

Wednesday, June 17, 2009

Measuring the Unmeasurable

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.

Sunday, June 14, 2009

What Needs Doing

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?

Wednesday, May 6, 2009

Quality Developers

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.

Sunday, April 19, 2009

Library Services

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.

Wednesday, April 15, 2009

Managing the books

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.

Friday, March 13, 2009

And now for something completely different

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.

:)

Sunday, March 1, 2009

What Executes?

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?

Wednesday, February 25, 2009

Why Models Shouldn’t Be Programs

Here's a great post on "why models shouldn't replace programs":


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!

Sunday, February 22, 2009

More Exec Design tools

I'm a fan of even partial solutions to the executable design problem. Here is are a couple I find particularly interesting.

DataXtend

http://www.progress.com/dataxtend/index.ssp

I had the opportunity to run a 1-week in-house live test of DataXtend. We took a bit of design from a set of web services we had delivered using Apache Axis and a lot of back-end Java code, and gave a design spec and the original interface specs to the DataXtend team. They showed up in our office on Monday and we did a little work on reviewing their capabilities. On Tuesday, we started working on the project, which had taken our offshore development team 6 weeks to develop (admittedly, that's way longer than it should have taken, partly due to continuous changes in the requirements, and partly due to just poor development management). By late Tuesday afternoon, we had a working web service. I load tested it; I threw bad input data at it, and I deployed it in several different environments, and it just worked.

We ended the 1-week demo in 3 days.

This tool is a slick as it gets. You import your interface design, expressed in XMI or as a schema or whatever (there are lots of options), you map it to your data sources, again specified as XMI or schema or whatever, and push the button. You get a working web service in a nicely packaged deployable file, with very little, if any, coding.

This isn't executable design--but it leverages the design very directly and very easily. You simply import the interface, and import the source services and/or data, and map one to the other. It's state-based implementation at its slickest. It's expensive, but it's a whole lot less expensive than a fleet of Java coders. We figured we could replace 6 developers and 2 leads with 1 lead and this tool. Nice.

MQArchitect

http://www.mqsystems.com/MQS-Solutions.html#mqarchitect

I haven't actually had a chance to use this tool, because I no longer have access to a large MQ installation. I have, however, been tasked with architecture in a large, fast MQ environment, and boy, oh boy, do I wish I'd had a chance to play with it. I did download the demo and tried it, and as far as I can tell without actually pushing 100k transactions/hour through it, it really works.

The basic idea is that you design your queue environment using some templates in Visio, and then you generate your whole system from that drawing. MQ is a pretty simple tool at the core, but there is a lot of connection and configuration data, and you have to get it right, or your nice fault-tolerant system fails badly, and worse, quietly. Fortunately for me, I had a couple of MQ wizards configuring my back end for me, but if you don't (and most of us don't), this may well be the right tool for a designer trying to keep track of a complex MQ system. Check it out.

If you have a tool I should look at, please drop me a line. I'm jdandrews on Twitter, and you can email me at jerry.andrews at gorillalogic dot com.

Wednesday, February 18, 2009

Abstraction

A design must an abstraction. A design constrains and informs an implementation. It allows developers to focus their creativity on a smaller set of problems. In fact, the whole point of the architecture/design/coding division of labor is to allow creativity and problem-solving to be applied on a small set of problems--problems which one individual can get their head around and thereby have a reasonable chance of solving. If you lose the ability to abstract by forcing the whole application into a single model, you have lost something important--you have, essentially, "jumped to code" before you understood the problem.

The problem with abstraction is that, without at least one working example, it's hard to tell if the abstraction makes sense. (Two good friends of mine are fond of saying "all abstraction is good, as long as it's your abstraction.) In new development, then, the ideas behind an executable design clearly have a place; they're a way to validate the abstraction actually does what it says it does.

As Bill Glover pointed out in his comment on an earlier post, applications get complex and crufty with time. He asks (with regard to reverse-engineering an existing implementation): "What will keep the design from being obscured by the kind of detail that starts showing up then? ... An example would be all of the methods and attributes that developers add to a class that aren't really relevant to the high level design, but are needed to make the class really do it's job."

What Bill's talking about, I think, is the very real and common case where you're trying to bring order to an existing application by describing its existing design. If, for example, you have a tool which can execute class diagrams (e.g. the GXE), how do you use that serve as an "armature" for the rest of the implementation?

If you just want to verify that the design and the implementation match, you're not in executable design space--you're in static code analysis space. There are tools for that (e.g. http://www.ndepend.com/). If you want an executable design to be an armature for the application to be built on, then you're really refactoring. The trick here is to allow the tool to replace some part of the application's existing functionality without a complete rewrite. Here are two example behaviors I think a tool might implement which would allow them to operate in an existing application, replacing part of that application.

I once introduced a state machine into an application which had significant business logic embedded in its screen navigation subsystem. I rewrote the navigation for just one screen, pulling out the business logic into separate classes for each business rule, and describing the screen-to-screen navigation in a state diagram. The state machine responded to user events (e.g. button clicks), queried the new business logic classes to get guard results, and handled transitions within and off of the one screen. Clearly, this approach can be extended to other screens without disrupting the application as a whole (and in fact, the development team for that product is doing just that).

I'm currently working on a project which is using an executable design tool (the Gorilla Execution Engine) to validate requirements. Classes representing domain concepts and relationships are executed in the GXE to see if the very complex calculations modeled by those classes give the "right results". In my ideal world, we'd then take that domain model, specialize it (that is, turn it into a design model), and it would enforce class behavior in the finished product. I might reverse engineer a dozen classes which participate in a given calculation, remove or hide the methods which aren't germaine to that calculation, then add new methods from the domain model to flesh things out. I might remove irrelevant methods from the model entirely. The execution tool would provide a class loader which would:
  1. load the design model,
  2. upon a class load request, it would search the model for a definition of the requested class,
  3. look for any class implementations of the same class,
  4. compare the two, merging them if the the implementation does not contradict the design model, and complaining loudly if it is not (this step could actually be done at build time rather than runtime), then
  5. load the merged class for execution.

An approach like this would allow the designer and developer (sometimes the same person, right?) to work together to decide what portions of the existing application could be replaced with an executing design. This would address a problem I see a lot, where the code can't actually be traced back to any requirements or higher-level design. By forcing the code to match the design in order for it to run, the design gets updated because it's the best way to get the build to work.

Of course, developers could always decide they don't want to execute the design, but they always have that power. I'm assuming that designers and developers are working together to build something; if they're not, the organization has issues no tool can address.

Sunday, February 15, 2009

The Role of the Executable Design

Stu Stern (http://stu-stern.blogspot.com) raised the question: "What would the executing design itself provide?" That's a big question, and I wanted to think about it in a longer context than "comments".

One role of an executing design is to verify the design.  Recalling the original motivating idea: an executable design which actually does what you say it does validates the design--it gives you a way to be sure that what you're handing to coders is actually going to be useful to them, and is going to work as envisioned.  I think this is hugely important--even if you can't ever use the executing design in the finished product, you get strong assurance that you're not going to start building something which won't work. Remember that mistakes in design cost a lot less to correct than mistakes in code--so spending a little on tools and time in design is quite likely to save money downstream--in coding, deployment, and operations.

In the design verification role, execution tools must then carry all kinds of simulation capabilities. In complex problem domains, they must be able to handle very complex class definitions and interactions.  In large systems, they must be able to simulate network latencies, distributed transaction failures, large loads, and similar system events. In short, in an executable design suite, this would be a different set of tools than those which might use the executing design as a framework for a finished product.

A second role is to constrain and inform the design.  Almost everywhere I work, designs are assembled in linear fashion as design documents (there's a good article, somewhat tangential to this discussion, in the January 2009 issue of Communications of the ACM: the "Ontology of Paper": http://mags.acm.org/communications/200901/?pg=26. The author argues that paper design documents are an idea whose time has passed.)  Design fragments expressed in UML are exported from the design tool as images and pasted into the document.  The whole thing is handed off to implementers for coding. These folks proceed to translate those diagrams and associated text into classes and subsystems and packaging.  When the design changes (as it inevitably must, when requirements become better understood and original design approaches don't pan out as expected), the loop is seldom closed by updating the design.  When the application moves to maintenance, the coupling between requirements and implementation quickly becomes hard or impossible to discern. Maintenance costs much more than it should, as new designers and developers spent far more time than necessary trying to understand what's there so they can update it intelligently.  The problem is exacerbated in agile projects, which are, effectively, in maintenance from the first day a new programmer joins the development team or a key one leaves.

If the design itself formed a key part of the finished deliverable--it's skeleton--then the design would always be in sync with the deliverable, and the extra step of translating what has already been built in design space into code space would be skipped.  What a boon for developers, designers, and maintainers!

A third role might be to constrain the implementation--to complain if the implementation diverges too far from the design.  I'm not sure how this would work, though I have some ideas, which I'll flesh out in future posts.

Wednesday, February 11, 2009

Disclaimer, and Some Links

I work for Gorilla Logic (http://www.gorillalogic.com).  I joined the company back in August 2008 because I wanted to work on and with the company's "Gorilla Execution Engine", recently open-sourced at http://code.google.com/p/opengxe.  It executes state processes, static class diagrams, and use cases, and is the best example of what I'm trying for as I have seen to date. I think I'm objective about the GXE; feel free to call me on it.

I started the Exec Design project on sourceforge (http://execdesign.sourceforge.net) some time ago to work on the same set of problems the GXE solves.  Some work is still going on there, as we have a lot of ideas to try out, and that seems like as good a place as any.

The obvious starting place for executable designs in UML are the behavioral models: interaction diagrams (sequence, collaboration), activity diagrams, and state charts.  Oddly, I've not seen anything which executes interactions or activity diagrams.  There are, however, lots of state machines available in open source.  All the ones I’ve played with merely execute user code, which is exactly how executable design should work: the designer provides the framework, but coders still write the detailed code.  This approach (especially if your state machine can execute the UML state process diagram directly) is exactly what I mean by executable design.  Coders still code; we don’t create a new language and expect designers to use it to fully specify the final system, but we do fully leverage designers’ work in UML.

My first state machine (http://execdesign.sourceforge.org) implementation requires developers to implement specific interfaces to specify guards, actions, triggers, etc.  This approach is too restrictive.  We want the tools to be able to do this, yes, but it should be part of the design, not a limitation of the state machine itself.  I implemented it that way to force developers to separate these things in code, but I hadn't thought through the problems it introduces, and I wouldn't do it that way now.

There’s a state machine which runs Argo UML state diagrams directly (http://unimod.sourceforge.net); I haven’t had time to look into the tool yet, but a cursory look at their web site indicates it may be an interesting project.

The GXE state machine is quite powerful, but I haven't worked with it enough to provide a good review, so I'm going to postpone that for the weekend update.

Given what I said last Sunday about executable designs, here are some characteristics I think an "executable design" engine or suite should have:
  • Developers can extend the model in a natural way.  For example, if the design specifies a method on a class, the developer just creates the appropriate class file and codes the method.  The execution engine melds the class in the model and the class as coded according to appropriate rules.
  • The model constrains the design.
  • The engine supports a widely-understood modeling language.
  • Code generation is an invisible part of using the engine, if it must be done at all.
  • The execution engine should be "invisible"--that is, it shouldn't take a whole lot of scaffolding in every modeled object to use it. Both the GXE and most state machines I've used are great examples of this; you start up the execution engine, and it "just runs" your model.
Well, that's a starting point, anyway. I haven't tried hard to boil these down or determine completeness yet, but I will over the next couple of weeks.

On code generation: I have seen some very powerful code generation systems.  There are two problems with code generation, though: 1) the generated code is usually pretty ugly, and 2) the design is distorted by the need for developers implementing the design to work "with" the code generator.  This is an example of a highly-visible execution engine, so perhaps my last wo bullets are really saying the same thing.

Several people have pointed me at some niche products in this space as well; I'll look at some of those tools over the next few weeks as well.

Sunday, February 8, 2009

Executable Design

When I first “noticed” architecture, I found it pretty much irrelevant.  At that time, designers generally talked rather than drew, or they drew flowcharts. Design documents were either 1000-page tomes or they didn’t exist at all. The architect with whom I worked generated block diagrams at such a high level they weren’t useful to me at all, or worse, they were misleading, because the actual system didn’t match the architecture in anything but name.

At some point, I finally started saying “architecture must be executable.” At the time, I meant that a designer/developer should be able to take an architectural description, code to it, and though it would be a skeleton, it should execute.  It should be possible to mock all the key system functions using nothing but the architectural description.

If feel the same way about design: if you can’t use the design as an actual blueprint, it isn’t a design–it’s a concept.  Concepts are good, but they must be refined into architecture and designs.  That’s what designers and architects get paid to do.  It’s hard work.  It’s boring sometimes. And it’s very very difficult to do well, which is why there are so few good designers, and even fewer architects.

I'm trained as a nuclear engineer, and I worked in power plants as such for 15 years before moving to software development full-time. Power engineers would laugh at what usually passes for a software design.  When you design a building, you aren’t done until you can predict the construction cost and schedule to within 5%.  Same thing goes for an engine, or a CD player, or chemical dye. In other industries, you’re working with real materials, which cost a lot, and whole teams of people, who also cost a lot.  You can’t do most of the work yourself, so you must explain exactly what you want done.

The same thing is true of large software projects (agile ones included--I'll get to that in future postings).

As software developers, designers, and architects, we have a huge advantage over engineers: our cost of implementation is very low. As a result, sometimes it really is cheaper just to throw code at the wall and see what sticks.  In medium and large projects, though, it is seldom the case that this approach will work more than occasionally. As a result, we build design documents.  Designers and architects make UML descriptions (hey!  we have our own design language!) and associated text, which we then hand to developers to turn into code.

Which is incredibly wasteful (and now I’m getting to the point).

UML is a succinct, precise way to specify a design.  Why do we have to translate it into code to get it to execute?  Wouldn’t it be a great test of a design if you could run it before you lobbed it at developers to flesh out?  I’m not talking about code generation here; I’m talking about directly executing the design components to see how they work together.

The model-driven architecture (MDA) folks are running down that idea.  I’m not sure I like where they’re going with it, though. I do not think it’s a good idea to turn designs into complete applications. Designs are abstractions, and the whole point of that abstraction, and the ability to separate architecture, design, and development, is to allow people to think at different levels of detail, so they have the capacity to grok the whole application.  Divide and conquer. I do think, though, that recoding the design from UML into some other language is wasteful. Wouldn’t it be a lot more productive to give developers an executing design and let them flesh out the details in their language of choice?

The rise of virtual machines–Java and .NET specifically, but I’m sure there are others–makes me think we can build executable designs, and code to them rather than recoding them. I’m currently working on “how”. I’d like to know what you think of the idea.