Write the Client Code First

May 31, 2008

“Always implement things when you actually need them, never when you just foresee that you need them.”

–Ron Jeffries

In his book Guerrilla Sales, Jay Conrad Levinson outlined an approach to selling that at first seemed backwards: Close the sale first, then pitch what you’re selling. The idea was that, rather than trying to coerce a client to buy your pre-determined offering, find out what the client wants first, then give it to them. Your service is then tailored to match precisely what the client requires—no more, and no less.

There’s an analogue in software development: Any time you have code that will provide a service and client code that will consume that service, write the client code first. In other words, don’t lock down lower-level code and then struggle to make higher-level code use it. Whenever possible, let the client code dictate the requirements for the code it uses.

Writing the client code first means:

  • Do nothing more than stub the return value of a function until you finish the client code that uses it.
  • Write code that uses a class before trying to finalize the class’s implementation.
  • Build the UI before writing controllers.
  • Write your controllers before writing data-access objects. (Better yet, auto-generate your base DAOs, and only add methods as the controllers require them.)

The rationale for building software this way is compelling:

  • Precision — Identify and build exactly what is required, when it is required, in the order required; no more and no sooner.
  • Speed — With priorities made clear and bloat squeezed out (or at least deferred), your delivery will be fast.
  • Rapid Feedback — Make your work visible to customers early so that you get their feedback right away.

If this seems like it should be a no-brainer, you’re right; it should be. And if agile development is second nature to you, you might wonder why this article was written at all. But most software still isn’t built this way, and as a result, most projects takes longer than necessary and don’t satisfy requirements as precisely as they should.

Defining the Finish Line

Face it: Your customers have no imagination. You’re more likely to be struck by lightening while winning the lottery than find a customer who thinks about building software the same way you do. And face it: You’ll probably never understand their business like they do, but they will assume that you understand what they want. Unless you can both agree on how to define “done,” you’ll eventually have a disagreement to settle.

How do you bridge this communication gap? Well-written use cases aren’t bad, but they’re not enough. Wireframes are good too. But there’s an even better way: Write the client code first, starting with the UI. Assuming you’re building web-apps, expressing requirements as static pages is by far the best technique I’ve ever seen for creating a common understanding about what you’re building. It’s the clearest way to define the finish line: “When these screens perform functions X, Y and Z, we’re done with this phase.”

Prototyping like this takes write the client code first to its logical extreme, since the UI is the ultimate client code in your application. Build it first, get it right, then use it to drive requirements.

Get the Fastest Possible Feedback

Customers can’t really picture how they will use software until they see something that looks like the finished product. The sooner you give them that, the sooner they can correct any errors in your assumptions.

Prototyping static screens is especially suited to web-app development, where it’s fast and easy to “demonstrate” functionality with stubbed navigation and dummy data, without having to build the full MVC stack. Once the screens and their behavior are agreed upon, bring the UI to life by implementing functionality a piece at a time. Your progress is immediately and continually visible to the customer, so course corrections are quick and small.

This has a tremendous advantage over bottom-up development, in which functionality isn’t visible in the UI until very late in the development process, often after it’s too late to make changes quickly.

Top-down Minimalism and YAGNI

“We will encourage you to develop the three great virtues of a programmer: laziness, impatience, and hubris.”

–Larry Wall

The laziness that Larry Wall referred to is “The quality that makes you go to great effort to reduce overall energy expenditure.” Writing the client code first reduces unnecessary work to the absolute minimum.

If, like me, you spent much of your early career building software from the bottom up—data layer first, then business logic, and saving the UI until last—building from the top down might seem utterly backwards. After all, the bottom-up approach has intuitive appeal; it just seems to make sense, and it’s easy to understand. So what’s the problem?

The problem is that it’s incredibly wasteful. It takes longer than necessary, and it breeds overly complex solutions to simple problems.

Bottom-up development is wasteful because assumes too much. It is based on a notion of completeness that says, “This service/class/layer won’t be complete unless it has every feature a client might need.”

This concept of “complete” is an illusion. You may assume that if there’s a requirement to add and delete items, there are also needs to edit, recycle and restore them. As often as not, assumptions like these prove false, and building functionality before there’s a concrete requirement for it is almost always waste of time.

Given a little time, requirements will always:

  • disappear, meaning you won’t need to build it after all
  • change, meaning you’ll need to modify or rewrite what you’ve built
  • become clearer, meaning you’ll need to modify or rewrite what you’ve built

“Pre-emptive implementation” is also wasteful because it robs you of time for more important things, like building functionality that’s needed sooner, or refactoring, or releasing earlier. Or having a life, or taking a vacation. Building more than you need now means that you’re on the hook for testing and debugging more than necessary, and it’s often unclear what tests will validate a feature that isn’t actually used anywhere.

The Extreme Programming maxim You Aren’t Going to Need It (YAGNI; occasionally misspelled YANGI), advocates a minimalist approach in which you build only what is needed to satisfy immediate requirements. Requirements and priorities change so frequently that it is a waste of time to try to predict them too far in advance and build everything “just in case” it’s needed.

Since it represents users’ actions, the UI defines requirements for the controllers (or application layer). For example, if the UI needs to display a list of users currently online, then a controller must provide that list, and in turn the User class must provide a getOnlineUsers() method. Development of the UI doesn’t even need to wait for getOnlineUsers() to be fully implemented; in the short term, the method can just return an array of dummy User objects. But you wouldn’t automatically implement methods like getAllUsers() or getInactiveUsers() just for the sake of “completeness” until there was an actual, immediate requirement for them.

This approach has some big overlaps with practices like test-driven development, client-first development, and behavior-driven development.

Counterpoint

In theory there is no difference between theory and practice. In practice there is.

–Yogi Berra

I’ve yet to hear a credible objection to top-down development by anyone who has actually done it. Debates on the subject seem to revolve around how it theoretically might not work or exceptional cases where it doesn’t apply. These ignore the reality that in practice, top-down development has a phenomenally high success rate in the vast majority of cases.

Usually the arguments are some version of, “It will take more time to build it later than if we build it now.”

No, usually it won’t. Or, at least, not much longer. This notion seems to stem at least partly from misapplication of a principle of software QA in which bugs found early cost a lot less to fix than bugs found later. Rarely is this argument relevant in modern, modular architecture. (It might be worth noting that you’ll never have to fix bugs in code that is never written.)

Even if it did take a little longer—or even twice as long—the extra time would be more than offset by the time saved by not writing (and testing, and debugging) features that aren’t ever used.

Further Reading

Comments

Comments are closed.

Spawn PHP Framework

Learn all about installing and working with this easy-to-use MVC framework.

Continue reading »

Coming Soon: Scaveng

Scaveng is a scriptable web scraper. Stay tuned for more.