Upload
michael-peacock
View
562
Download
1
Embed Size (px)
DESCRIPTION
Citation preview
Registry Patternwith lazy loading goodness
Michael Peacock
The
whois michaelpeacock.co.uk
• Experienced senior / lead web developer
• Web Systems Developer for SmithElectric Vehicles US Corp
• Author of 6 web development books
• Owner / CTO of CentralApps LimitedJust launched first beta product: invoicecentral.co.uk
• Zend Certified Engineer
Commonly used objects and settings...
Within Bespoke frameworks and large applications most of the code often needs access to core objects, settings and variables.
...such as
• Database Access / Abstraction layers
• Template engines
• Object for the currently logged in user
• Objects which perform common tasks, such as email sending or data processing
• Site settings: path to uploads folder, cache folder, site URL, etc
The solution: Registry
• Create a registry to store these core objects and settings
• Provide methods to store and retrieve these objects and settings
• Pass this object around your application (e.g. To your models and controllers) –or- make it a singleton (yuk)
Registry: basics<?php
class Registry {
private $objects = array();private $settings = array();public function __construct(){}public function storeObject( $object, $key ){}public function getObject( $key ){}public function storeSetting( $setting, $key ){}public function getSetting( $key ){}
}
?>
Registry: concept codepublic function storeObject( $object, $key ){
if( array_key_exists( $key, $this->objects ) ){
//throw an exception}elseif( is_object( $object ) ){
$this->objects[ $key ] = $object;
}}
public function getObject( $key ){
if( array_key_exists( $key, $this->objects ) && is_object( $this->objects[ $key ] ) ){
return $this->objects[ $key ];}else{
//throw an exception}
}
EASY!
Registry: usage
• Make your code awarePublic function __construct( Registry $registry){
$this->registry = $registry;}
• Store an object$this->registry->storeObject( $template, ‘template’ );
• Access your objects$this->registry->getObject(‘template’)->output();
Registry: The good
• Keeps core objects and settings in one place
• Makes it easy to access and use these objects and the data or functionality they hold within
• Common interface for storing, retrieving and managing common objects and settings
Registry: The bad
• All aspects of your application need to be registry aware...
...though its easy to simply pass the registry via the constructor to other parts of your code
• Works best with a front controller / single entry point to your application, otherwise you need to duplicate your registry setup throughout your code
Registry: The ugly
• Bloat!
• If you rely on the registry too much, you end up with objects or settings which you only use some of the time
• This takes up additional resources, time and memory to setup and process the objects and settings for each page load, only for them to be used 50% of the time
Registry: de-uglification
• Make the registry lazy loading
– Registry is aware of all of its objects
– Objects are only instantiated and stored when
they are first required, and not before
– Registry knows about core settings/data that is
used frequently, and knows how to access
other data if/when required
De-uglification:
• Make the registry aware of its objects
$defaultRegistryObjects = array();
$db = array( 'abstract' => 'database', 'folder' => 'database', 'file' => 'mysql.database', 'class' => 'MySQLDatabase', 'key' => 'db' );
$defaultRegistryObjects['db'] = $db; $template = array( 'abstract' => null, 'folder' => 'template', 'file' => 'template', 'class' => 'Template', 'key' => 'template' );
$defaultRegistryObjects['template'] = $template; $urlp = array( 'abstract' => null, 'folder' => 'urlprocessor', 'file' => 'urlprocessor', 'class' => 'URLProcessor', 'key' => 'urlprocessor' );
De-uglification If the object isn’t set, load it the lazy way
/** * Get an object from the registry * - facilitates lazy loading, if we haven't used the object yet and it is part of the setup, then require and instantiate it! * @param String $key * @return Object */
public function getObject( $key ) {
if( in_array( $key, array_keys( $this->objects ) ) ) { return $this->objects[$key]; }elseif( in_array( $key, array_keys( $this->objectSetup ) ) ) {
if( ! is_null( $this->objectSetup[ $key ]['abstract'] ) ) {
require_once( FRAMEWORK_PATH . 'registry/aspects/' . $this->objectSetup[ $key ]['folder'] . '/' . $this->objectSetup[ $key ]['abstract'] .'.abstract.php' );
}require_once( FRAMEWORK_PATH . 'registry/aspects/' . $this->objectSetup[ $key ]['folder'] . '/' .
$this->objectSetup[ $key ]['file'] . '.class.php' ); $o = new $this->objectSetup[ $key ]['class']( $this ); $this->storeObject( $o, $key ); return $o;
}}
De-uglification: settings
• Apply the same approach to settings / data
• Query your core settings
• If the setting requested hasn’t been loaded, load all related settings (works best if you prefix your keys with a group name)
Conclusion
• Easily access your core objects, functionality and data from anywhere in your application
• Apply some lazy loading to keep your application running lean
• Enjoy!
Any questions?
www.michaelpeacock.co.uk
www.twitter.com/michaelpeacock
www.invoicecentral.co.uk