Tag Archive for 'Architecture'

Ohm – Least Resistance

A few astute readers have noticed that there was a new section, titled Ohm, in the blog header above. They have written in private to ask me, and were shortly included in the private beta testing phase for the project. That phase has now come to an end, as I now reveal the project to begin its open beta testing phase.

ohm-70x70Ohm – Least Resistance is a lightweight PHP 5.2 framework designed to be as simple as possible. You can use Ohm before your morning cup of coffee. If you need to do something clever or unusual, you can read the Ohm source code to find out how you can bend it to your needs: it’s only 2,000 lines, comments included. And Ohm conveys this simplicity to your own code, if you are willing to accept its philosophy:

1. Most frameworks can be extended because there are configuration options for every single piece of behavior. Ohm can be extended because it’s extremely simple.

2. Most frameworks help the programmer write code faster, often pushing the dynamic nature of PHP beyond its safe boundaries. Ohm recognizes that reading code is harder than writing it, and helps the programmer write code that is easy to read later on.

3. Most frameworks try to become repositories for countless pieces of useful but highly specific functionality. Ohm concentrates on being a HTTP/PHP/MySQL framework.

The Ohm framework is open source. In fact, its code is in the public domain, though I appreciate references and/or links back to the project page. What you get by downloading the framework:

  • Class auto-loader : finds your classes based on their name, so you don’t have to use require and include all over the place.
  • Request dispatcher : responds to HTTP requests by loading the appropriate action class and executing its response method.
  • Model-View-Controller : the framework layout follows the MVC pattern and helps your application do so as well.
  • Reusable Layouts : lets you define generic page templates that will be wrapped around the actual template. You can insert JS/CSS into the layout from the content.
  • Simple Forms : a backbone module for creating, processing and drawing HTML forms that you can extend to fit your needs.
  • Database Layer : a dead-simple extension on top of mysqli that lets you have an easier time writing SQL requests and retrieving the data, without having to learn a new query language.

If you have any questions about the framework, you can contact me directly (victor-ohm@nicollet.net). Any comments and feedback are welcome (this is an open beta, after all), either by mail or as comments on this post.

Enjoy!

Open-Source

ppt1ppt2ppt3

Software Inbreeding

You’ve seen one of these painful, horrible business applications, uglier than hell and with no thought put into consistency or usability. No sane person would use them, but they are still used because that’s what the company paid for and that’s what the employees are going to use.

The root cause of all this suffering? Think about it : who is going to write a piece of accounting software?

Choice A : the competent former accountant who happens to know something about programming. But he’s not an expert, so he uses some PHP4 he stole off the web instead of leveraging open source tools that are too hard for him to change, he writes <marquee> everywhere because he never heard of growl, he makes weird mistakes related to unicode (which he believes is a Nazi encryption scheme from 1944) and he steals assorted icons from the 1990 Macintosh world because FamFamFam’s silk is too esoteric for him to know about.

Choice B : the competent programmer who happens to know something about accounting. [Insert here striking examples about how incompetent programmers can be when dealing with accounting :) ] And he might get bored before the end, because accounting is boring to engineering types (and that would be assuming he even knew there was a need for an accounting application in the first place).

With Choice B, you get a symphony of Ajax-CSS3-HTML5 beauty and pixel-tuned usability, but you can’t use accrual-based accounting because the programmer never heard of it, and you just can’t use an accounting program that doesn’t handle accrual-based accounting if you’re serious about it. So, you use Choice A, which is an ugly-as-hell, retina-maiming, CTS-inducing threat to humanity that handles accrual-based accounting.

People try to solve problems they are familiar with. It does not surprise me in the least when Dharmesh Shah notes ten recurring themes for young software start-ups to work on. To wit:

1. Project Management / Time Tracking / Bug Tracking
2. Community / Discussion Forums
3. Personalized News Aggregation/Filtering
4. Content Management (website, blog)
5. Social Voting and Reviews
6. Music/Events Location Application
7. Dating and Match-Making
8. Personal Information Management
9. Social Network For ______
10. Photo/video/bookmark/whatever sharing

If you’re a programming genius, not only do you have a good idea of what features these applications should have, but you would actually be standing in line to use them as soon as they are available.

On the other hand, you don’t wake up every morning to do a little dance, thinking «Woo, this order-printing application will kick so much ass!» And even if you managed to get excited about the project as a technical challenge(Woo, this next-gen F#-and-AJAX application, which happens to print orders, will kick them butts all right!), the tedium of identifying hundreds of fields and entities and relationships and business rules, and typing them in, can’t really be considered a technical challenge. And F#-and-AJAX won’t help if your ER diagram is off, so you have to ask the accountant, who will promptly bore you to death with an in-depth explanation of international VAT deduction rules.

And that’s a shame, because the non-programming hoi polloi are stuck with software from the 1980s that can’t be replaced until all the features are replicated by the new solution.

Dealing with software older than yourself is always a traumatizing experience. Think of the children.

EDIT: Seth Godin published a post around being passionate about tax accounting at the same time I published this post… my sneaky mind control schemes for owning the internet must be working.

Back/Refresh/Bookmark

A feature shared by almost any web search engine in existence is the ability to return to the list of results if the result you check out wasn’t what you hoped it would be. Even better, you actually return to the same page in the search results that you were on in the first place, so you can just resume your search.

Sounds obvious?

It is, when you’re using a technology straight out of the 90’s such as plain vanilla HTTP. The original problem that led to the design of HTTP was that you had many resources publicly available on the web, but there was no simple way to tell your friends where the latest naughty lady bitmaps important accounting files were. Thus were born the Uniform Resource Locators, known nowadays as URLs, which obviously helped locate resources in a way that was uniform across servers. Of course, for this to work, reaching out for the same URL twice should bring back the same piece of data both times (or, at the very least, a piece of data that is similar within reasonable expectations, such as being the “latest version” of the same data).

This is what HTTP GET does: locate and fetch a resource from the tubes, bringing back the same resource every single time.

The GET method means retrieve whatever information (in the form of an entity) is identified by the Request-URI.

This is why your web browser can implement back, refresh and bookmark but your SSH client can’t. And this is also why HTTP POST does not play nice with back, refresh and bookmark (it involves posting data, which may have an impact if done more than once, such as double-posting on a forum).

The Good

Google et alii play into this game: every search result page is a resource, which can be located through an URL that contains all the information about that page. Of course, the resource is generated on the fly on the server, but to the user (and the browser) it looks as if a static resource was present on the internet, so pressing the back button brings you back to the same URL, and this yields the expected data.

Note that many web browsers will also remember some other things about the visited page, such as the scroll position and any text you entered in the fields. This is important, because this lets you refresh a page without losing the data you entered.

The Bad

Of course, it’s hard to think in terms of resources-each-bound-to-locators when you’re not dealing with resources. And besides, the “user gets form, user posts form, user is redirected to new page” mechanism can be quite limiting when you’re trying to be clever. And it all looks so different from how desktop applications work!

I am regularly brought on the brink of intellectual suicide when faced with “web applications” that maul the very spirit of HTTP with spiked baseball bats covered in hot pepper oil. No back, no refresh, no bookmark… These designers hope (and in this, they are quite correct) that as long as their application looks and feels like an application, there will be no affordances that would cause the user to use these forbidden buttons.

A list of elements is the most ubiquitous example in modern computing: clicking on an element opens a detailed view of that element. The “application” way of doing this is opening a new window to display the details, so that the user may close the window or cancel their way out of it to go back to the list. No sane user will try to use the back feature to return to the list, because that’s not how the desktop taught us to behave.

This can be imitated on the web with a new browser window, or with a modal window using javascript and (possibly) AJAX.

On the other hand, if the application replaces the list with the detailed view, then it’s using the “web” way of doing things, and the “show me the previous screen” reflex of pressing back will kick in really soon. Too bad pressing back breaks the application. And pressing forward again to return to a reasonable state won’t work either.

I will not delve into the sheer stupidity of moving against affordances that are so deeply ingrained in the average internet user for design reasons (and even doing so for technical reasons is pretty bad).

The Ugly

And then, there’s the matter of AJAX. The good thing about AJAX is that it lets you dynamically update only a part of your page, without having to refresh the rest. The bad thing about AJAX is that it lets you dynamically update only a part of your page, without having to refresh the rest.

That’s because every single thing you did on your AJAX page will be lost the moment your user presses back or refresh. If your lists are managed through AJAX, then the user will navigate to page 3, then click on the link, which will bring them to another page, then press back, which will (as expected) bring them back to the page with the list… that was reset to page 1, because there’s no way for the browser to know that the complex javascript state that kept your list on page 3 had to be remembered in the history.

For a real-life example, try this link (from the ExtJS library), click around a bit, and then refresh — you’re back to step zero. Since everything happens on a single page in a new tab/window, there’s no back button to be used.

The good news is that there are tricks available for handling back/refresh/bookmark in JavaScript. Another example would be this one, from ExtJS again, which handles the back part almost correctly (still no luck on refresh/bookmark), or this example based on the excellent jQuery Address plugin, which manages to do all three properly.

The hash : a hack on top of a hack

Back in the days where documents could be quite large in order to be handled offline as a single file, people had to come up with a way of navigating though them. The adopted solution was to use anchors. Somewhere in your file, you would add a named anchor, such as <a name="myAnchor">. Then, appending #myAnchor to the URL of the document would scroll the anchor into view (well, the anchor was invisible, but you get my meaning).

So, you could link to a part of a document from the document itself by using the URL-with-hash as the target of a link. And you could link to it from other pages, which let you send your readers to the appropriate location on the referenced document.

It became fairly standard for web browsers to implement this system so that:

  • Clicking on an anchor (or changing the anchor part of the URL) would not reload the document if it was already being displayed.
  • The anchor was taken into account by back/refresh/bookmark.
  • JavaScript would have read-write access to the anchor part of the URL (usually as window.location.hash).

This, in turn, provides several ways of solving the back/refresh/bookmark in heavy JavaScript situations.

The first one, used by the ExtJS example above, is to alter the hash every single time you change the application state in a relevant way (what is relevant is left for the developer to decide), and simultaneously push information about the state in some kind of storage.

Then, as the user presses forward and back, the hash-changing will keep the user on the same page and let the JavaScript read from the storage whatever state needs to be applied to elements and restores that state accordingly. The problem is that, when the page is refreshed (or bookmarked and loaded later), everything but the hash will disappear in a puff of garbage-collected smoke, so that no memory of the stored states will remain.

The second solution is to store those states in the hash, so that they will be available even if you refresh, or bookmark the link, or give it to someone else.  This is what the jQuery Address example does, by storing the name of the selected tab in the hash, and then reading that name from the hash to activate the relevant tab whenever back or refresh happen.

Deep Linking

Quick note: this solution is sometimes referred to as deep linking. In fact, deep linking represents the very ability to open any page in a web site by entering its URL (so, if you find this article in a Google search, then Google is by definition deep linking into my site so you can access the article directly). As explained above, deep linking is a natural consequence of how HTTP works:

The conclusion is that any attempt to forbid the practice of “Deep Linking” is based on a misunderstanding of the technology [...]

The entire point of those hash-based tricks is to enable (or restore) deep linking in heavy JavaScript web sites. Quite ironic, given that not so long ago we were trying to forbid it.

The Middle Path : a hash behind the hash

Of course, between those two solutions, there’s the middle way: store some fundamental information in the hash, and keep the rest in a separate storage area. This way, back will be fully functional, refresh will still manage to keep enough relevant information around to be useful, and the hash will be small enough so that it remains below allowed size limits.

This third strategy is quite simple to manage by starting from the second approach, keeping a global hash table to store the detailed state, and adding the key of the current detailed state to the summarized state.

This is basically saying, store the current (detailed) state of components A and B in the hash table with key 0x3ffc, then store 0x3ffc in the hash along with the current (summarized) state of component C. When that hash is reactivated because of back, the detailed state will be available based on the key, and when reactivated because of refresh, the summarized state will be replaced and the unavailable detailed state will be replaced by defaults.

Model Zero : Keep Stuff Around

The simplest situation for this kind of thing is when developers absolutely need to keep some part of the page on the user’s computer. It could be, for instance, a media player that has to remain present on the page even as the user browses the web site. Refreshing the page would drop the media player, which would cause the music to stop, so the page must stay, and content must be updated on the fly.

Of course, you don’t want to have AJAX-related link problems: Google does not follow JavaScript links, so if the entire link tree of your website is implemented in JavaScript, only your home page will be known to Google.

A classic design technique found on Deezer is to keep two URLs for every page. One URL contains the hash, the other doesn’t. By default, links use the non-hash URL, and as such can be followed by Google. If JavaScript is enabled, links automatically start using the hash URL instead.

For example, the non-hash URL for a search for “nicollet” on Deezer is:

http://www.deezer.com/en/music/result/all/nicollet

The hash URL for that same search is:

http://www.deezer.com/en/#music/result/all/nicollet

Both display the same page, so the algorithm for displaying the hash URL is basically, “load all the data for the non-hash URL and use it, while keeping the few elements that have to stay around, such as the music player”. Quite simple, and it does not detract a lot from the typical way of designing web pages in a non-AJAX world.

Sure, Deezer is flash-based, but equivalent JavaScript techniques are used by Facebook when they need to keep a chat box around, and (if you need a public JS-based example anyone can visit) by Jukebo.fr.

This is actually what the jQuery Address plugin was designed to do: run through all the links on a given page and turn their no-hash URL targets into hash-based URL targets, then provide the user with a “hash was changed” event that they can respond to by doing whatever they feel should be done (such a loading bits of data from the server for the new URL).

As a whole, Model Zero is fairly simple to implement and use, and requires only minimal support from the server, such as controllers that display partial views instead of complete views if called with a certain parameter.

Model One : Components on a Page

… starring Samuel L. Jackson. This is the simplest model that does not involve simply mirroring server-side pages on the client, and it usually happens when a normal page contains some kind of JavaScript component, such as jQuery UI tabs that are expected to be refreshed appropriately, or an ExtJS grid with complex state.

The assumption here is that you don’t care about Google following the links in your grid (jQuery UI tabs decay to a nice HTML markup when JS is disabled, so they would create no problems), but you do care about your user using back/refresh/bookmark on the page.

The basic idea is that every single component on the page has to be connected to the history handler (be it Ext.History, $.address or anything else) so that they notify it of their state changes, and are notified in return of external address changes.

Depending on which component you are trying to connect to which history handler, things will be more or less difficult. In the rather common situation where you wrote your own component, it will have to provide a “my state changed” event (triggered by your component whenever user interaction causes a change of state) and a “give me a new state” function (called by the history handler whenever the state changes). Somewhere along the way (probably in your component) you will need a serialization-deserialization utility to turn the complex state of your component into a hash-storable string and back.

For additional safety, make sure that setting a state that is already the current state does not trigger the state change callback: depending on your history handler implementation, it might cause an infinite loop, and it ain’t pretty.

A quick-and-dirty example to connect jQuery UI tabs to the jQuery address plugin (this should not work as is, and is intended merely as an illustration):

$(function(){

  $.address.externalChange(function(){
    var i = $.address.value().substr(1) || 0;
    $('#tabs').tabs('select', i);
  });

  $('#tabs').tabs({
    select : function(event){
      $.address.value(
        $('#tabs').tabs('option','selected');
      );
    }
  });
});

The first part extracts the state from the hash and selects a tab, the second part reads the currently selected tab and activates it. It relies on the tabs not firing a “select” event if the selected tab was already active, and on externalChange not being triggered by setting the value from the code.

Note that the second part does not compute the new hash value from the event itself, but rather from global data: this is because, if you had two components on the same page, changing any of the two would have to store the new state of both components in the URL. In that situation, you would have a single “compute the hash based on the state of both components” function triggered by the on-change events of both components.

Model One-Dot-Five : what if I use both of the above?

What happens if you load your pages using model zero, and then you have components on these pages that use model one?

This is not very difficult, but it requires some cooperation on the part of model zero, which “owns” the hash for practical reasons. The first possibility is to have model zero use only one channel of your history management tool—for instance, if your tool allows you to specify query strings, you can store your state as ZERO?COMPONENT=STATE&COMPONENT=STATE without difficulties.

The second possibility is to have model zero provide an interface that lets components from the loaded pages register and control parts of what model zero will save to the hash through a modification to its serialization process (again, the query string seems like an obvious choice).

The problem is that the first possibility will not work…

First: since you always remain on the same page, components that disappear from the page do not remove the events you registered with the history manager to handle them. It is the responsibility of model zero (which knows when a page content change happens) to eliminate any callbacks registered by components from model one. Otherwise, on every URL change, all callbacks will be processed, which reduces performance, causes memory leaks and might, in really nasty situations, cause a component on a page you visited five minutes ago to maul the URL of the page you’re visiting right now.

Also remember that the hash-was-changed event will trigger an AJAX reload of the page contents, so the new components will by definition not be present on the page when the event is triggered!

So, model zero reloading takes a little more effort now:

  1. Detect that a reload is required.
  2. Unregister all hash change event handlers registered from child components.
  3. Query the content, insert it into the page. It may contain components, which will then register themselves with the hash change event.
  4. Propagate the hash change event to the newly created components.

Since it now needs to unregister child handlers and propagate the hash change after loading is done, model zero needs tighter control over how children are connected to the history handler. I believe the only clean solution here is to make model zero a global object that wraps around the history handler, so that child components only need to interact with the global object.

An interesting interface for this part of the global object would be:

zero.onChange(callback)
Registers a callback to be called whenever the state of the child components needs to be modified (because of an URL change). Child components, when they initialize themselves, register themselves this way to listen to URL changes. All callbacks registered this way are discarded when the contents of the page change.

zero.setState(dictionary)
Changes the query string part of the URL to take into account changes that happened to child components. This does not trigger the change event.

Being global means components initialized in <script> tags in the incoming, server-sent HTML can still reach out for it and register themselves.

Model Two : recursive boxing

When you look at the previous model, you notice that model one components inside a model zero page is a flat structure only waiting to be made recursive. The key to this is to create a component that acts like a model zero page by loading its content from the server and passing down some information to its own child components.

Model Three : client controllers

This model gives up any kind of non-javascript usage of the web site. A classic example is gmail (and, just like gmail, you can provide an alternate static HTML version of the web site with greatly reduced features). This approach basically leaves everything in the hands of the JavaScript programmer by letting him define the application as a stateful component, with the hash in the URL being a serialized version of the component state (or the relevant parts thereof). It’s also the hardest to work with, since there’s basically no high-level architecture, though you may implement a domain-specific one like gmail did.

Building Hammer Factories

I recently acted as a technical advisor to a small start-up company that was having difficulties getting their product out the door. The situation there reminded me of this “Hammer Factory” post by BenjiSmith:

“So this week, we’re introducing a general-purpose tool-building factory factory factory, so that all of your different tool factory factories can be produced by a single, unified factory. The factory factory factory will produce only the tool factory factories that you actually need, and each of those factory factories will produce a single factory based on your custom tool specifications. The final set of tools that emerge from this process will be the ideal tools for your particular project. You’ll have *exactly* the hammer you need, and exactly the right tape measure for your task, all at the press of a button (though you may also have to deploy a few *configuration files* to make it all work according to your expectations).”

That start-up company wanted to provide various groups of customers with online services. Those customers would have similar high-level needs (buying and keeping track of sports accessories*), but different segments would have different specific needs (football teams need to keep track of numbered shirts with appropriate sizes and only buy a dozen each year, while rock climbing groups need to purchase rope and chalk on a weekly basis*). The business plan called for starting with the basic functionality, and being able to quickly provide each segment with a specifically tailored version of the online service within months of the initial launch.

(*: the business plan has been anonymized to protect the innocent.)

Obviously, if you write the basic application without paying attention to what the tailored versions will need to provide, you will end up in trouble for the quickly part. The smart people at that start-up realized that and went all the way to the other extreme: the basic version would actually be a fully configurable application, so that the development of segment-specific versions would be as simple as ticking a few checkboxes.

Needless to say, this kind of decision increases by a large factor the cost of initial development:

Even writing your own reusable code is orders of magnitude harder than just jotting down a quick one-shot solution to whatever problem you have. An excessive tendency to build generic code from the very beginning makes your development process look like Dragon Ball Z : you have to power up for fifteen episodes before you can show a splash screen.

The long road from «everything must be done by writing new code» to «everything can be done by ticking checkboxes» is a form of optimization that tries to reduce the time and skill required to perform certain tasks. Like any other optimization process:

  • Doing it ahead of time without access to profiling data can often result in unnecessary or insufficient modifications. While humans are better at estimating their own time than they can estimate computer processing time, they’re not perfect, and it’s not easy to determine how often a given task will have to be performed.
  • If a given task represents only 1% of the time spent by humans using the application, then even a 1000% improvement will not improve the application by more than 1%.

Back when I worked as a freelancer, I worked with a client that wanted a poll system for their website. I offered them a choice between a complete poll system (to be designed and implemented in around four days)  that would let them create new polls at will, or a simple system (designed and implemented in half a day) that would require a couple of hours for a moderately skilled developer every time a new poll was needed.

They asked me for the four-day package.

In six years, they have changed the poll three times. Every time, the change was performed by their in-house developer. One of these times actually required the developer to add support for a new feature.

Was it worth it?

Why I Gave Up on the Zend Framework

The Zend Framework is a really nifty thing. Really, it is. The amount of functionality that you get merely by installing it is extremely exciting: internationalization, forms, an MVC layout for your program, a cute class loader, a database abstraction layer, a templating engine, a request dispatcher, mail-sending functions, pretty debugging “dump” functions… and there are so many people working on it and using it that basically all the bugs left in there are shallow. It has been a staple dependency of many of my projects for quite a while now, and still is.

Zend Framework is actually available for your projects in two flavors, «use what you need» and «obey the hive mind», with a continuous spectrum in-between these two extremes.

We are Zend. Resistance is futile.

We are Zend. Resistance is futile.

The «use what you need» approach leaves the maintenance programmers with a warm and fuzzy feeling. All you have to do is dump all the framework files somewhere in your include path, include the files for the bits you want to use, and just call the functions. The framework takes care of recursively including the appropriate dependencies for you and carefully avoids treading on any toes by prefixing everything with «Zend».

In fact, if you use Zend_Loader, you can skip the include-source-files step completely (except for Zend/Loader.php obviously), and since auto-loading is reverse-compatible with loading files manually, it’s also a good step towards a well-deserved refactoring.

So, if you need to send multi-part mail, with HTML-and-text content, in UTF-8 format, you can just use Zend_Mail and everything will work fine regardless of the rest of the code base. There are dozens of such small features (for PDF generation, LDAP, access control, localization, and so on).

There is virtually no excuse for not using a plug-in class from the Zend Framework in your application if it solves the problem you’re having. Besides, since the files are not included until you need them, the worst that could happen is that you’re having some PHP code taking up a few megabytes of disk storage for nothing. So I have a lib/Zend directory on all my projects, just in case I need something.

Obey the Hive Mind

While many pieces of Zend are independent of each other, there’s a central functionality core that’s designed to act well together. There are many examples:

  • it’s easier to use Zend_Dispatcher and Zend_Controller together.
  • it’s easier to render a Zend_View if you’re also using Zend_Controller.
  • it’s easier to turn a Zend_Form into HTML if you’re using Zend_View.
  • it’s easier to set up a “login already in use” validator with Zend_Form if you have a field in a Zend_Db_Table to connect it to.
  • it’s easier to translate Zend_Form error messages with Zend_Translate (and Zend_Registry).

Sure, it’s usually possible to take advantage of 99% of the functionality without having to add new dependencies, but there’s always that tiny voice in the back of your head, nagging that you could get that additional 1% so easily if you just gave in.

Giving in means, of course, going all the way to Bootstrap heaven: now your project is laid out across the lines of the ideal Zend Framework template, your files cleanly stashed in their folders with a cosmic Feng Shui feeling to it all, and the Zend approach to MVC pervades your every HTTP request.

This isn’t so bad: actually, such an approach has some huge selling points for shops that write lots of small projects, such as the ability to get 20% of your basic functionality up and running in days, the ability to hire any Zend-certified developer and not have to educate them about the framework, and you don’t need them lousy architects on your team.

I’ve had some trouble with the Zend way before, though. There are some bits of functionality that I won’t touch with a ten-foot-pole, such as Zend_View, Zend_Controller or Zend_Db_Table, because the havoc they wreak in situations I find myself in outweighs the benefit.

Documentation

My main issue is that I find Zend quite lacking on the documentation side.

«But the Zend Framework is possibly the most documented there is!» you say, before trailing off in a rant about how the “FM” should be “R” and the “FW” should be “S”.

You’re probably right. But I don’t really care about that documentation. I’m talking about project documentation—to know what happens in code written by my team.

«What does Zend have to do with that? Document your code, you lazy slob!»

Humans are lazy, and I would argue that laziness is actually an essential quality of a good programmer. I can require that documentation be written, but I expect it to be missing, inaccurate or monosyllabic. Things like that happen when you’re rushing out a bug patch at 3:00 am. And even if I could ensure that documentation is written and kept up to date, I’d rather have my code be self-documented—not only does it take less time, but it’s harder to get inaccurate self-documentation and you can even get the language to check things for you.

It’s the difference between documenting the parameter type as a @param MyClass $obj in a comment and documenting it as a MyClass $obj type hint in the function signature.

Look at the average .phtml template, and you’ll see something like this:

<div>
  ...
  <a href="<?php echo $this->getUrl() ?>"><?php
    echo $this->escape($this->user->name)
  ?></a>
  ...
  <?echo $this->partial('preferences.phtml', $this->pref); ?>
  ...
</div>

Half the point of a view in the MVC approach is that I should be able to easily reuse that view from any controller, or even from within another view. Of course, Zend lets me do this very easily:

$view = new Zend_View();
$view->xxx = yyy; // Fill in members
$view->render('template.phtml');

The red line, of course, is where trouble begins. Since Zend_View fields are by definition dynamic, there’s no way to get auto-completion to help you find what they should be. Nor can you look at a list of these fields in a class definition or function definition, because there’s none. You have to read the template file and find out by yourself what values are used by the template and what their types should be. Oh, and if the template passes some of that data to other templates, you have to read those templates too, because they might use specific information. And you have to look at view helpers too, because they might be accessing view elements behind your back.

Your best bet is to look at an existing controller that uses the view, and hope that you don’t stray too far from what that controller is doing. You never know: a certain member might be expected to be present if another has a certain value (this never happened with the first controller, but it happens in yours), there’s no compiler checking that all values are being provided appropriately, and runtime testing doesn’t reveal such special cases on the first try.

And they say Zend_View is an object-oriented approach to rendering…

The most important aspect of Zend_View templating is that it is object oriented. You may use absolutely any value type in a template: arrays, scalars, objects and even PHP resources. There is no intermediary tag system between you and the full power of PHP. Part of this OOP approach is that all templates are effectively executed within the variable scope of the current Zend_View instance. To explain this consider the following template.

That’s not what object-oriented means. OOP means if two views behave differently, then they should be instances of different classes, instead of injecting arbitrary code and data into a single class and spitting in the face of encapsulation.

The bottom line is that reusing Zend_View templates is a pain in the derrière unless you take special steps about it (steps that you wouldn’t need with a standard class-with-members).

What’s in that row?

This is futher compounded by the way Zend_Db works: an ORM that generates SQL from a sequence of PHP calls, and then turns the result into a list of Zend_Db_Table_Row objects. Which leads to the question of what fields can be found in a given row, and that question is hard to answer.

A typical application will follow a rule along the lines of «every table row is, by definition, a row of a table, so you just peek at the table definition and you know that each column is mapped to a field,» and that is a fine rule to follow, because then the only issue is you can’t type-hint the row based on the table, so you can’t make sure a given argument is always a row from “account”.

But following that rule is hard. In addition to those 80% plain old CRUD cases where you’re working with a single table at once, you’ll have those 20% that use joins where you need data from both tables (never mind the pain of doing that in PHP). Then you end up with a row that breaks the rule, so you keep it in tightly enclosed areas of your application, until it gets too frustrating not being able to use a view-that-renders-accounts on a record-that-contains-accounts-and-sessions, and the next thing you remember is that you don’t know if a given view expects an account or an account-and-session.

And the language can’t help you.

Auto-complete me

Nor can your editor, for that matter, since auto-completing $row-> requires knowledge that your editor simply cannot have (the list of columns defined when you configured your Zend_Db_Table).

I really do enjoy it when my code editor helps eliminate some of the tedium of writing code. In fact, I’m quite ready to make a small additional effort tagging my members, arguments and functions with some type information just so that writing code can be easier.

My editor is Eclipse PDT. It has several nice features that I use extensively.

The first is, of course, its ability to suggest members of classes and objects. Having well-defined classes to represent your data means that Eclipse can use the type hints you leave around to determine that $account is of class Account, so that it has a $firstname member. That’s:

  1. one less round-trip to the database documentation
  2. zero chances of typing $account->firstName by mistake
  3. being told immediately if $account has entirely different members (because it’s another type)

Since Zend_Db_Table_Row and Zend_View actually go out of their way to make sure that you can have arbitrary data in there based on runtime considerations, getting this functionality out of them is impossible.

The other nice feature I use a lot is the ability to control-click a class or function to see its definition. This lets me navigate around the code in seconds instead of having to open the project file explorer, expand several layers of directories usually far from each other, and spend precious brain power translating a class/member naming scheme into file naming schemes.

Finding a file is a job for the editor, not for the programmer.

My view helpers look like this:

View_Account::renderSimple($account);

Clicking on that function name brings up the file and scrolls it down to where it matters. Took me less than a second. Zend View Helpers look like this:

$this->renderSimpleAccount($account);

I dare anyone to navigate to the definition of that helper in less than a second. [EDIT: apparently I shouldn't dare people on the internets :) ]

What about links? The typical approach to generating a link to a different part of a site, with the Zend Framework, is to spell out its controller and action:

<a href="<?php echo $this->url(array(
  'controller' => 'user',
  'action' => 'edit',
  'id' => '123'
));?>">click me!</a>

Now you have to click on every single URL on your website to make sure links are correct and you still manage to forget one and the end user will click on that link that’s spelled out as «edti». And even if you do get it right, you still have to navigate to the appropriate controller class, open it up and scroll down the right action.

My urls look like this:

<a href="<?=Action_User_Edit::url(123)?>">click me!</a>

Since every one of my actions is a class (as opposed to a function in a controller class), they get to have members, and one of these members is a static url() function that:

  • lets me ctrl-click through to the action itself
  • has PHP check that my link is correct (or else, die with a class-not-found answer)
  • documents the expected URL arguments as function arguments
  • even lets me find out who links to a certain controller, in case I have to move it

The bottom line…

…is that I don’t use Zend_View, Zend_Controller or Zend_Db in my projects. I need my code to be self-documenting, and there’s nothing self-documenting about Zend_View or Zend_Db. I need my code to be easy to navigate through and simple enough for my editor to handle, and the full dynamic behavior of Zend_View and Zend_Db prevent that.

Your needs might be different. Are they?

Shouldn’t Happen…

Design and development is turning the great unknown chaos into tiny bits of controlled functionality with promises about what the result will be, and expectations about what the input should be.

There is an interesting duality between two categories of expectations, depending on whether they are the responsibility of the user, or of the programmer.

User errors are classic mistakes involving incorrect input, such as attempting to load a file that does not have the right format, or visiting a web site that does not exist, or entering an incorrect email address. A program is expected to, at the very least, gracefully handle these situations (because nobody likes errors) and the best programs are actively designed to reduce the possibility of error though appropriate user interface choices.

Programmer errors are the most frequent ones, but most of there are luckily caught by a compiler (or, in the case of the less lucky interpreted languages, the parser). The basic idea is that if you expect a function parameter to be an integer, and you tell your compiler, then static analysis will determine that you will receive a string argument, and the universe will collapse build will fail.

Static Analysis

Static analysis can be very smart. It can prove beyond any doubts complex properties about complex software written in obscenely low-level code (such as C with inline assembly). The problem if that working with a static analysis tool can add unusual constraints on the developers themselves: the halting problem dictates that no tool can safely predict the behavior of a program, so any given tool will either have false negatives (undetected bugs) or false positives (safe code reported as dangerous) and the general trend for static analysis tools is to avoid any false negatives at the cost of false positives.

The quality of a static analysis tool is determined by how hard it is to write code without false positives (usually done by manually coding around the blind spots of the tool).

Static analysis tools have two problems. One, they’re not available for every single language and platform out there. Some of use are still using languages with eval(), throwing Java exception-safety out the window because we find it too constraining, doing without those pesky type systems and generally making a childish fuss about those “warning” thingies. Two, static analysis tools can only check constraints that are described by the developer in some form, such as assertions, preconditions, postconditions, type annotations or some other kind of attribute added to the code.

So, if you forget to “assert” it, nobody is going to check it for you. For instance, no tool is going to warn you that you unwittingly leak a credit card number to a third party.

The Elephant Statue

In a sense, predicting user errors is the mirror activity of gathering specifications. Both force you to think about all possible situations your software will face, and decide what should happen: maybe you have to display an error, maybe you will have to tread the input in a clever but predictable way, or maybe you will have to rework your process to prevent that situation from happening.

This is akin to creating an elephant statue by starting with a block of stone and carving out everything but the elephant. Deciding what your users can do implicitly defines what your users cannot do. Depending on the situation, you may guide your design with either approach.

Interest(ing) rates

The most common way of investing money is putting it in a savings account. You lend a fixed amount of money to someone, and they pay interest over that money at a predetermined rate. Let’s say you lend 1,000 € at an interest rate of 3%, paid every year: at the end of the year, you would receive 30 € as payment for your lending. You would spend these on fine wine or nice clothes and wait until the next year to get another 30 €, and so on.

Savings accounts work on the basis of simple interest : what you get paid is a linear function of both time and money. Lend for half a year? 3% ÷ 2 = 1.5% Lend for two years? 3% ×2 = 6%

An important thing to bear in mind is that interest is paid at fixed intervals, for instance at the beginning of January. You don’t have to spend those 30 € : you can them on the savings account and earn simple interest on them after a year (3% of 30 € is 0.90 €).

Using this strategy, lending for two years is done at a 6.09% rate instead of 6%, because you get interest on interest. This is known as compound interest : what you get paid is an exponential function of time. Lend for two years ? (+3%)² = +6.09% Lend for three years ? (+3%)³ = +9,27%

The mathematical justification is that, with a 3% interest, your total amount of money is multiplied by 1.03 every year:

1,000 + 30 = 1,000 + 3% of 1,000 = 1,000 + 0.03 × 1,000 = 1.03 × 1,000

So, after two years, the amount is multiplied by 1.03 two times, and so on.

1,060.90 = 1.03 × 1,030 = 1.03 × 1.03 × 1,000

In short, percentages have a multiplicative effect.

And now, pop quiz : I’ve gained +5% weight over the winter holidays. What percentage of my weight do I have to lose to be back to normal ?

If you answered -5%, you missed the point. Multiplicative effect means the total change of weight would be +5% × -5% = 1.05 × 0.95 = 0.9975 = -0.25%. I would be losing too much weight !

The correct answer was 1 ÷ 1.05 = -4.76%.

Similarly, if the number of graduates of a given school increases by +10% on year one and +25% on year two, the total increase is +37.5% and not +35%.

Duality

This is where mathematicians (and computer scientists) use an interesting little concept called duality. Percentages are numbers that are easy to understand, but hard to combine. We can transform them into something that is a little bit harder to understand, but easier to combine.

The traditional way to transform multiplication into addition is to exponentiate, due to an interesting property of the exponential function:

exp(a) ×exp(b) = exp(a + b)

So, I wish to find a percentage operator (§) such that:

  • we conserve some values, 0§ = 0% and 100§ = 100%
  • applying A§, then B§, is equivalent to applying (A+B)§

Then this uniquely defines an operator which is called exponential percentage:

A§ = B%  ↔  A = 100 × log(1 + B ÷ 100) ÷ log(2)

Some common values:

0% = 0§ +100% = +100§ -100% = -∞§ 200% = 158.4§
+1% = +1.4§ +99% = +99.2§ -1% = -1.4§ -99% = -664§
+10% = +13.7§ +90% = +92.6§ -10% = -15.2§ -90% = -332§
+25% = +32.2§ +75% = +80.7§ +50% = +58.4§ -50% = -100§

percent

So, if I gained +5§ weight over the holidays, I can lose -5§ weight and be back to where I started, and if a number increases by 10§, then by 25§, it increases by 35§ overall.

And of course, a yearly interest rate of 4.2§ = 3% compounded over ten years is 42§ = 34%.

No Free Lunch

Normal percentage rules make compounding hard, but it’s reasonably easy to estimate a percentage based on a fraction. Exponential percentage rules make compounding easy, but evaluating a percentage based on real figures is harder.

In practice, compounding happens less often than evaluating, so humans use normal percentage rules. And computers are good at compounding through multiplication, so they don’t need exponentiation.

Duality does have some other uses, though. For instance, there’s the duality between two representations of complex numbers:

a + ib = r exp iθ

The cartesian (a,b) notation makes it easier to add numbers, but multiplication is harder:

a + ib + c + id = (a+c) + i(b+d)

The polar (r,θ) notation makes it easier to multiply numbers, but addition is harder:

r exp iθ × s exp iφ = (r × s) exp i(θ+φ)

For mathematically-oriented computer scientists, duality is a gold mine, because it lets one reduce a complex problem in one area to a simpler problem in another area (whether simpler means faster, as in the case of FFT, or easier to think about)..

The Law of DSLs

There’s one common duality that is fundamental in the computer world: the correspondence between data and code. In a fit of narcissism, let me sit wisely atop a tall mountain to announce Nicollet’s Law of Domain Specific Languages:

Any sufficiently complex data processing algorithm is as an interpreter for a small domain-specific language, and the data being processed is a program executed by the interpreter.

In some cases, this law only complicates things further. In many cases, however, the different angle it provides leads to many advantages, one of them being to transform a non-programming concept (such as an accounting file format) into a concept programmers are familiar with (a programming language).

A minimalist language design culture is enough to grasp several interesting concepts about executing code, which can be quite handy when processing data:

1. Compile to Bytecode

Interpreters don’t execute a string of characters. They tokenize that string, turn the tokens into an abstract syntax tree representing operations, functions and variables, then turn that syntax tree into a sequence of small, executable operations. That sequence is then fed into a virtual machine (or further compiled to machine code) to perform the actual operations.

If the input data for your algorithm is very complex, you can begin on the other side: what will the algorithm do with the data? Will it be inserting the data into a database? Constructing a data object from bits and pieces? What you are looking for is a set of atomic operations you can apply to generate the result. Implement these operations, then start working on a translation algorithm to turn the input data into such operations.

There are several common and friendly representations for such atomic bytecode:

Instruction lists are executed in order. This is your classic assembler listing, without the jumps. A typical “parse file and insert into database” algorithm would generate such an instruction list, and every instruction would be an INSERT, DELETE or UPDATE. Works best when you can read the data and generate the instructions in the right order: if you cannot get the list in the right order from the start, consider another approach.

Dependency graphs work like makefiles: you have several instruction lists floating around with relationships between them, indicating that one list has to be executed before another. A topological sort of the graph results in a single classic instruction list you can execute. A multi-file import, where some files contain data needed in other files, can be the way to go.

Nested scopes are the typical extension to instruction lists: every item in a list can be either an instruction, or another list, possibly tagged with some data. This could be a conditional (if this condition is true, execute this list), a loop (though it is best to avoid these) or a context (a “polygon” scope contains “insert vertex” operations that apply to that polygon). You can even allow variables in a let-in fashion (of which the polygon example above is just a special case) ! Note that nested scopes can be easily represented as XML.

2. Static Analysis

A side-effect of compiling to bytecode is that you get to process the entire file before you actually perform the intended operations. This makes a rollback easier if you notice that there’s an error on the last line of the file: if you make sure that no atomic operation in your target language can fail due to bad input (such as incorrect data values), then you can check your input data for correctness without doing anything to your program state.

Even better, if your compilation process is cheap (linearly traverse a file for parsing) and you have heuristics for predicting how much time and resources your individual instructions require, then you can try to accurately predict the needs of the entire process.

Static analysis also means you can optimize. If, for instance, you’re inserting data into a database and need to resolve names or keys frequently (such as “add this item to list #732″), you can easily construct a table of needed keys (that you can get in one query when the processing starts) using the dependency graph approach.You can also optimize resource allocation by using common register allocation techniques: sort your dependency graph to keep as few resources in memory as possible at any given time.

3. Caching

Try to perform most of the processing offline.

For instance, if you frequently “apply” one file to another, such as a nearly-constant “list of categories” file used to resolve the “category” key in a daily object import, you can benefit from compiling the nearly-constant file to an easily loaded, easily applied format.

You see a cached dictionary that maps keys to categories? I see a DSL that allows dictionary literals as part of the language, and a source file that contains a literal mapping keys to categories, with an interpreter that can apply constant propagation to dictionaries.

Another benefit is when applying changes to mission-critical software. Inserting lots of data into a web database can create a heavy load on the server and make the site unavailable to visitors. It might therefore be preferrable to pre-compile the imported data into requests through a process that keeps a light load on the server, then run the requests.

Besides, with proper nested scoping, you can slice an import into several transactions. This keeps the lock count low, allows spreading the transactions over time to reduce the load, and lets you resume the import process if, for some reason, it gets interrupted.

Do It Yourself

Unless you’re working in an esoteric field on the bleeding edge of technology, the vast majority of programming problems you face have already been solved many times by many other people, and several of these solutions are readily available on the web or in legacy code libraries you might have access to.

To solve a problem, you can

  • reinvent a particular wheel : the non-factored approach, since you create your own instance of that wheel,  or
  • reuse one of its existing implementations : the factored approach, where several projects benefit from the same piece, including your own.

Both alternatives have costs and benefits that the experienced software engineer is aware of, and these will depend on your exact problem somewhere along the lines of :

1

The time spent solving a problem steadily increases with the size or difficulty of that problem, and is further subject to two important rules.

Non-factored is cheaper for small problems

A factored solution carries some overhead because it is used by several projects with different scopes. The “one click, 200 words” bias happens when non-technical managers hear “leverage an existing solution”, and see a picture of a one-click installer and a 200-word tutorial telling them their particular problem can be solved with two lines of C# code.

HolyGrail grail = new HolyGrail();
grail.doWhatIMean(/* No options here! ^_^ */);

Yeah. Riiiight.

Every one of us has spent days reading up on third party libraries just to decide if they are worth the effort, slaying compatibility dragons to make it talk with the rest of the project, filling hundreds of configuration options that have no relevance whatsoever to the tiny problem at hand, teaching co-workers about the nooks and crannies of that code, and painstakingly wading through less-than-civilized error reporting to solve the obtuse problems that come up on the day before you release.

Even writing your own reusable code is orders of magnitude harder than just jotting down a quick one-shot solution to whatever problem you have. An excessive tendency to build generic code from the very beginning makes your development process look like Dragon Ball Z : you have to power up for fifteen episodes before you can show a splash screen.

This rule is the reason why the red curve stays above the blue curve for small problems.

Factored scales better for large problems

Solving a larger problem involves a larger solution. In a do-it-yourself situation, you have to make the solution larger yourself. When using a factored approach, you already injected an existing large solution into your project, and it only feels small because you’re using a small part of it. With the programming equivalent of flipping a switches, you get to use a larger part.

The solution that involves the most code (the non-factored one, in case you wondered) also involves the most maintenance, documentation and development work. Whether this comes from a thousand-line reinvented wheel or obscene copy-pasting, having a large code base is something you will have to pay for in the long run. You don’t buy code, you rent it.

This rule is the reason why the red curve ends up above the blue curve for sufficiently large problems.

Keeping these two rules in mind, the key to making the right decision is determining where the red and blue curves intersect, and where your project stands. Easier said than done. For instance, what does “problem size” mean, precisely?

Problem size can be, literally, the size of the problem for an obvious metric. A content distribution network like Amazon S3 is a bad choice for 1000 downloads per week, but an obvious solution for 1000 downloads per second.

Could be the things in the application that are similar to the one you’re implementing. Sending usage statistics back to your server is a small problem solved with a vanilla HTTP request. If you communicate with the server a lot, you might want to keep the URL and error handling logic together in one place.

Or it could be the number of features. Displaying data in table format takes two nested loops and some HTML. Sorting, filtering, asynchronous sending or editing involves some rather smart Javascript development, or integrating a tool like jqGrid or ExtJS.

Once, Twice, Refactor

The special case of writing your own reusable code has been “solved” by Agile folks who suggest writing a non-reusable version of the code on the first try, and refactoring it to a reusable version the second time it’s needed. This is your third choice : go with the non-factored solution if you are unsure whether the problem is large enough to warrant the factored solution, and change your mind as soon as you gather enough data.

2

This is a solution that costs less than the factored approach if the problem is small, and costs less than the non-factored solution if the problem is large, while keeping an acceptable overhead when the problem is somewhere in-between.

Of course, writing your own reusable code means that the cost of switching from the non-factored to the factored version is significantly lower than starting with the non-factored version from scratch, because you refactor the original solution into a reusable one.

The advantages are not so obvious when moving from one approach to the other involves throwing away all code and installing a third party application. You do get some benefits—at the very least, you know more about the problem that you did at first, and perhaps your first approach served as a useful prototype to further refine your needs—but doing this can hurt a lot.

So, you end up getting hurt if you don’t know what you’re doing. What a surprise.



693 feed subscribers
(readers who polled a feed this week)