Friday, July 18th, 2008

Reduce, Reuse, Recycle…. your code

With a young son, I often listen to the “Reduce, Reuse, Recycle” song by Jack Johnson for the Curious George movie. Edgar Hassler has taken that axiom and applied it to code.

Edgar goes into a lot of detail, including the following issue that he ran into:

The problem I kept having was that I needed to pass information from PHP’s environment to JavaScript imported into an XHTML document, and in that JavaScript document, I needed to reference other resources that were relative to the script file. CSS gets this right in that references to images in external CSS documents are read relative to the CSS document path. JavaScript, surprise, does no such thing. Plus, some scripts need to occur at certain locations in the document (which can be surmounted by the event stack in IE or the event queue in Firefox; if you feel the urge to cut yourself, you’re doing it right.) Finally, some scripts must be included before others, but I didn’t want to throw errors when someone imported one component before another.

We built something called Axon, which, for lack of a better description, allows for something like Java’s import statements. A package definition file (there can be any number of them) describes resource names like “Synapse.Forms.Validation” and maps them to required resource names (dependencies) and resource paths associated to channels. A channel was the end resource type, such as “CSS” or “JavaScript”, and mapped onto the Loader to manage which things are imported. Further, Axon recursively met the dependencies to ensure things entered the environment in the proper order. Lastly, we added a service definition so that a resource could describe itself as providing, say, “sendEmail”, and allowed the loader to be queried for a service.

Axon “worked” in that it made using our messaging bus system and form validation code easy. We used it everywhere. It failed in that we never used services, and no one remembers if caching is on or off, causing comically bad situations where bug fixes don’t work or, alternatively, performance tanks. Both great options.

and then concludes:

For PHP developers especially, notice that as we make our code more meaningful ad face, we may be sacrificing speed on the processor but we’re gaining huge amounts of development time, bug tracking time and fees for busted keyboards and restraining order hearings. That’s the hard sell—as a developer we have to deal with costs, and as PHP developers we have the advantage of being on an already “slow” interpreted language rather than writing assembly into our C++ for speed.

By focusing on reuse we gain savings directly and indirectly, as reusable components serve as a vocabulary to discuss a project.  We all feel the need for it, but it’s difficult to secure a way to ensure reuse. In an effort to sum up, I am suggesting requiring the following in your own projects:

  • Require that concerns be addressed one domain at a time, and composite those solutions as needed
  • Focus on writing semantic code (for which the meaning is obvious from its structure)
  • Document your code and include example use cases
  • Documentation should always include a description of what you are trying to achieve as well as what you are actually achieving with your design.  Be honest
  • Use composition over inheritence when adding features to multiple classes from the past, present and future (mainly when spanning different codebases)
  • Allow for high level uses via factories
  • Allow for low level uses via constructors and factories.
    (When PHP 5.3 lands, don’t let your constructors be public)
  • When something will be constant for a long time, provide a place to put that data once and reuse it, don’t demand it each time
  • Talk to people who will be developing with this piece of code, or pretend you are them, or actually be them and learn what concerns they have
  • Imagine refactoring an older project to use this code. Ask yourself what problems you forsee, and how can you make design decisions now to prevent these problems?
  • Release your code to a community that can use it (and ensure they can use it by releasing it at GPL3 or better.) Encourage feedback and participation
  • Drink a lot of vodka and red bull and black out when you code so that you can approach it with a fresh mind the following day
  • Request comments at every stage,  examine the gap between what they expect and what you’re planning on building, but ignore feature requests that would cause you to drift off target.  Do not try to complete components all at once, rather let it be something to which you come back.  Don’t rush it, just let it happen, baby
  • Do not fear trading small amounts of performance for semantic structure. You’re not developing mainframes or nuclear stockpile simulators, you’re building web apps in PHP and more often than not the most expensive thing is you, so pamper yourself
  • Be able to say that something is not a good candidate for re-usability.  If, over the course of time, you begin to notice yourself re-writing it again and again in a way that can be abstracted, then go for it, but it’s okay if not everything is part of a library
  • Be willing to use (or willing to consider using) existing libraries for reusable components.  It will get you in the mindset of your community and provides you with a bunch of tools you don’t have to build yourself

If you do these things, you’ll get rich quick working from home.  No, not really, you won’t, at least you probably won’t, because the results I’ve cited are not typical.

In fact, in the spirit of this article I hope any reader who makes it to this point writes a post on their own experience—what’s worked and what’s failed.  My psychic abilities tell me that several of you read this and said “whoa, that’s a recipie for a performance disaster,”  and when projects explode in popularity this criticism is most certainly true.  My “Highly Available Enterprise Application Architecture with PHP” post is twice as long and three times as ornery.  Also it is entirely written in Tamarian allegory regarding Darmok and Jalad.  But with Thrift, Smarty-like templates, EC2, a smart caching strategy, APC, memcached and a little shuffling of resources you can rebound.

As he says, what are your thoughts with respect to your code?

Posted by Dion Almaer at 7:08 am

4.1 rating from 20 votes


Comments feed TrackBack URI

As a suggestion to the Ajaxian crew: You might want to limit your comments, or at least, actually condense them. Is this some sort of nefarious trick aimed at keeping people on Ajaxian by printing the article here? Evil.

Comment by sandro — July 18, 2008


For what it’s worth, I *edited* the article and I’m just fine with the way they presented it here. Edgar went into a lot of detail and the narrative he provided wasn’t terribly compressible.

I think they did fine by us. :-)

–Chris Cardinal

Comment by disillusioned — July 19, 2008

Leave a comment

You must be logged in to post a comment.