Thursday 9 April 2009

Lazy getters

I've never really seen this style of programming used much outside of Magento and ZendFramework, so I don't know what to call it. I decided on "lazy getters" as a good enough term.

Lazy getters consist of a getter function that checks the item which it's going to get and initializes it if it's not set. Wait... that sounds normal you say? ... almost clever? Well, sounding clever is a lot different than actually being clever.


/**
* Initialize and retrieve application
*
* @param string $code
* @param string $type
* @param string|array $options
* @return Mage_Core_Model_App
*/
public static function app($code = '', $type = 'store', $options=array())
{
if (null === self::$_app) {
self::$_app = new Mage_Core_Model_App();

Mage::setRoot();
Mage::register('events', new Varien_Event_Collection());
Mage::register('config', new Mage_Core_Model_Config());

self::$_app->init($code, $type, $options);
self::$_app->loadAreaPart(..., ...);
}
return self::$_app;
}
As you can see, this function "app" simply returns a reference to self::$_app, unless $_app is not initialized. Then it uses the parameters passed into it to construct an app and do some initialization. Even the code comments say "initializes and retrieve an application".

When this style of get is used throughout your entire code base you end up with 2 problems:

1. You never know where/when something gets initialized, since everything is lazily loaded. It also makes it hard to search for the initializing portion of code since both inits and gets use the same function name.

2. It's slow. You might not think so, but using lazy getters all over your code guarantees that you cannot access any property other than with a getter, plus the checks for validity are always done each call to "get". The engine has to accommodate for all those optional parameters and create memory for them just to return self::$_app.

Number 2 probably doesn't seem like a big, but when that style infests your entire application, it's probably adding 10% overhead without any benefit. In fact, it's taking away clarity from the code a la problem number 2.

No comments: