Zend framework 03 - singleton factory data mapper caching logging
Upcoming SlideShare
Loading in...5

Zend framework 03 - singleton factory data mapper caching logging



Singleton & Factory, Dependency Injection, Data Mapper, Caching and Logging.

Singleton & Factory, Dependency Injection, Data Mapper, Caching and Logging.



Total Views
Views on SlideShare
Embed Views



0 Embeds 0

No embeds



Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
Post Comment
Edit your comment
  • Cons: 1. Hides dependencies - A component that uses one or more singletons is hiding crucial information about your dependencies. It doesn’t take long for calls to a singleton to creep through your code base like kudzu, slowly attaching itself to every class in the system. Exposing that dependency forces you to think about it as you use a component. It also makes it more reusable as the caller can understand its requirements and how they might be satisfied. 2. Hard to test - The hidden coupling of users on a singleton makes testing a nightmare as there is no way to mock out or inject a test instance of the singleton. Also, the state of the singleton affects the execution of a suite of tests such that they are not properly isolated from each other. 3. Hard to subclass - Since initialization occurs in a singleton in static code, it is not amenable to subclassing because subclasses inherit the initialization code without the chance to override it. 4. A singleton today is a multiple tomorrow - It’s not at all unusual to discover that you now need 2 or more of something you previously only needed one of. Hard-coding the singleton pattern into your code makes it impossible to satisfy that demand later. Think Upc_Pe_Db class..

Zend framework 03 - singleton factory data mapper caching logging Zend framework 03 - singleton factory data mapper caching logging Presentation Transcript

  • Zend Framework 3. Singleton & Factory, Dependency Injection, Data Mapper, Caching, Logging Tricode Professional Services www.tricode.nl Date: 27-02-2009 Authors: Marcel Blok Patrick van Dissel
  • Singleton
    • “ Ensure a class only has one instance, and provide a global point of access to it.”
    • – GoF
  • Singleton class Logger { /** * @var Logger */ private static $instance = null; private function __construct () {} private function __clone() {} /** * @return Logger */ public static function getInstance() { if (! self :: $instance instanceof self ) { self :: $instance = new self (); } return self :: $instance ; } } <?php $a = Logger::getInstance(); $a ->methodX(..); $b = Logger::getInstance(); $a ->methodX(..); $a === $b
  • Singleton
    • Pros:
      • There's always only one instance of the class
      • Easy to use
    • Cons:
      • Hides dependencies
      • Hard to test
      • Hard to subclass
      • A singleton today is a multiple tomorrow
      • It's a global variable! Globals are bad! So use with caution
  • Dependency Injection
    • “ Dependency Injection refers to the process of supplying an external dependency to a software component.”
  • Dependency Injection How can Dependency Injection be applied to the following code? <?php class Book { public function __construct() { $this ->_databaseConnection = new DatabaseConnection(); // or global $databaseConnection ; $this ->_databaseConnection = $databaseConnection ; } }
  • Dependency Injection
    • What does this mean for your code?
      • Enforce that an external dependency is provided to a class. Not instanciated and configured within the class itself
      • More reusable code
      • More testable code
  • Dependency Injection How is this? <?php class Book { public function __construct() { } public function setDatabaseConnection( $databaseConnection ) { $this ->_databaseConnection = $databaseConnection ; } } $book = new Book(); $book ->setDatabase( $databaseConnection );
  • Dependency Injection How is this? <?php class Book { public function __construct( $databaseConnection ) { … } protected function setDatabaseConnection( $databaseConnection ) { $this ->_databaseConnection = $databaseConnection ; } } $book = new Book( $databaseConnection );
  • Dependency Injection How is this? <?php class Factory { private static $_database; public static function makeBook() { $book = new Book(); $book ->setDatabase( self ::$_database ); // more injection... return $book ; } public static function setup( $database ) { …. } } $book = Factory::makeBook();
  • Dependency Injection
    • Dependency Injection makes sure classes have:
      • High coherence
      • Low coupling
    • What results in:
      • Reduced Dependencies
      • Reduced Dependency Carrying
      • More Reusable Code
      • More Testable Code
      • More Readable Code
  • Dependency Injection
    • Where should objects be instantiating and configured?
      • On the highest layer, eg. in the controller or in a factory
    • Doesn't that make the controller huge?
      • Yes, it makes the controller bigger. But also more in control and without surprises
  • Factory
    • “ Provide an interface for creating families of related or dependent objects without specifying their concrete classes.”
    • – GoF
  • Factory
    • Benefits:
      • A good alternative for the singleton pattern
      • Takes care of initiating objects
      • Can take care of configuring objects
  • Factory <?php class Factory { private static $_database; public static function makeBook() { $book = new Book(); $book ->setDatabase( self ::$_database ); // more injection... return $book ; } public static function setup( $database ) { …. } } $book = Factory::makeBook();
  • Persistency
    • Very good ways to persist objects are nowadays:
    • Object-relational DBMS (ORDBMS)
    • Object-orientated DBMS (OODBMS)
    • Space based architectures (SBA)
  • Persistency
    • Unfortunately often we have legacy data that is
    • stored and structured in:
    • RDMS
    • XML
    • Text files
    • Etc.
  • Object-relational impedance mismatch
    • The biggest challenge in persisting objects to
    • relational database management systems is the
    • mismatch between objects and tables.
  • Object-relational impedance mismatch  Database model Object model 
  • Data mapper Pattern
    • In order to stick to good OO design rules the code
    • for the object itself and for the mapping should be
    • separated (high cohesion).
    • The Mapper should know of the object, the object
    • not of the Mapper (low coupling)
  • Data mapper Pattern
  • Database connection
    • It is good practice to separate the code for creating the database connection from the Data Mapper (high cohesion)
  • Database connection Like a singleton
  • Database connection With a factory
  • Lazy loading
    • Load the data as late as possible
    • Lazy initialization Set initially to null and every request checks this
    • Virtual proxy A proxy object with the same interface that loads the requested object
    • Ghost Initialize with only ID, load the remainder when needed
    • Value holder Use a generic object that handles the lazy loading
  • Aggressive loading
    • Load all data as soon as the object is instantiated.
    • In some cases aggressive loading is more
    • appropriate:
    • All (or most) data is always needed
    • Resource costs are low (time, memory)
  • Zend_Cache Algorithm: No $data = false ; $data = $cache ->get(‘myKey’); if ( false === $data ) { $data = $db ->fetchOne(...); $cache ->save( $data , ‘myKey’); } echo $data ;
  • Zend_Cache
    • Frontend: How to cache
    • Backend: Where to cache it
    • Used by several other components in the framework
    • Use caching where possible to limit the number of requests to slow resources, eg. database queries
  • Zend_Cache
    • Theory:
    • Lifetime: every entry in the cache expires at some point
    • Commonly used methods:
      • get(): returns false when nothing found (a miss)
      • save()
      • remove()
  • Zend_Cache: Frontend
    • Different methods of caching:
    • Zend_Cache_Core (abstract)
    • Zend_Cache_Frontend_Output
    • Zend_Cache_Frontend_Function
    • Zend_Cache_Frontend_Class
    • Zend_Cache_Frontend_File
    • Zend_Cache_Frontend_Page
  • Zend_Cache: Backend
    • Generic interface for different cache backends
      • File (on disk)
      • Sqlite (database)
      • Memcached (in memory, distributed)
      • APC (opcode cache)
      • Xcache (opcode cache)
      • ZendPlatform (disk)
      • TwoLevels (combination of two above methods)
  • Zend_Log $logger = new Zend_Log(); $logger ->log(‘log this message’, Zend_Log::INFO); $logger ->info(‘log this message’);
  • Zend_Log Log priorities Debug messages 7 Zend_Log::DEBUG Informational messages 6 Zend_Log::INFO Notice: normal but significant conditions 5 Zend_Log::NOTICE Warning: warning conditions 4 Zend_Log::WARN Error: error conditions 3 Zend_Log::ERR Critical: critical conditions 2 Zend_Log::CRIT Alert: action must be taken immediately 1 Zend_Log::ALERT Emergency: system is unusable 0 Zend_Log::EMERGE Usage Value Name
  • Zend_Log Log writers Discards all log messages. This can be useful for turning off logging during testing or for disabling logging Zend_Log_writer_Null Sends log messages to the console in the Firebug extension of Firefox Zend_Log_writer_Firebug Stores logs to database records. You need to map the level and messages to two fields within a table Zend_Log_writer_Db Stores logs to files or other streams. The ‘php://output’ stream can be used to display to the output buffer Zend_Log_writer_Stream When to use Name
  • Zend_Log $logger = new Zend_Log(); // Log Warnings, Notices and Informational messages $writerMessages = new Zend_Log_Writer_Stream ($logsPath . 'messages.log'); $messageFilter1 = new Zend_Log_Filter_Priority(Zend_Log::WARN, '>='); $messageFilter2 = new Zend_Log_Filter_Priority(Zend_Log::INFO, '<='); $writerMessages ->addFilter( $messageFilter1 ); $writerMessages ->addFilter( $messageFilter2 ); $logger ->addWriter( $writerMessages );
  • References
    • Singleton and Dependency Injection
      • http://googletesting.blogspot.com /2008/11/clean-code-talks-global-state-and.html
      • http://en.wikipedia.org/wiki/Singleton_pattern
      • http://www.potstuck.com/2009/01/08/php-dependency-injection/
    • Anti-Patterns
      • http:// en.wikipedia.org/wiki/Anti_pattern