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

Like this? Share it with your network

Share

Zend framework 03 - singleton factory data mapper caching logging

  • 4,572 views
Uploaded on

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

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

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
4,572
On Slideshare
4,572
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
35
Comments
0
Likes
2

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide
  • 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..

Transcript

  • 1. 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
  • 2. Singleton
    • “ Ensure a class only has one instance, and provide a global point of access to it.”
    • – GoF
  • 3. 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
  • 4. 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
  • 5. Dependency Injection
    • “ Dependency Injection refers to the process of supplying an external dependency to a software component.”
  • 6. 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 ; } }
  • 7. 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
  • 8. Dependency Injection How is this? <?php class Book { public function __construct() { } public function setDatabaseConnection( $databaseConnection ) { $this ->_databaseConnection = $databaseConnection ; } } $book = new Book(); $book ->setDatabase( $databaseConnection );
  • 9. Dependency Injection How is this? <?php class Book { public function __construct( $databaseConnection ) { … } protected function setDatabaseConnection( $databaseConnection ) { $this ->_databaseConnection = $databaseConnection ; } } $book = new Book( $databaseConnection );
  • 10. 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();
  • 11. 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
  • 12. 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
  • 13. Factory
    • “ Provide an interface for creating families of related or dependent objects without specifying their concrete classes.”
    • – GoF
  • 14. Factory
    • Benefits:
      • A good alternative for the singleton pattern
      • Takes care of initiating objects
      • Can take care of configuring objects
  • 15. 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();
  • 16. Persistency
    • Very good ways to persist objects are nowadays:
    • Object-relational DBMS (ORDBMS)
    • Object-orientated DBMS (OODBMS)
    • Space based architectures (SBA)
  • 17. Persistency
    • Unfortunately often we have legacy data that is
    • stored and structured in:
    • RDMS
    • XML
    • Text files
    • Etc.
  • 18. Object-relational impedance mismatch
    • The biggest challenge in persisting objects to
    • relational database management systems is the
    • mismatch between objects and tables.
  • 19. Object-relational impedance mismatch  Database model Object model 
  • 20. 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)
  • 21. Data mapper Pattern
  • 22. Database connection
    • It is good practice to separate the code for creating the database connection from the Data Mapper (high cohesion)
  • 23. Database connection Like a singleton
  • 24. Database connection With a factory
  • 25. 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
  • 26. 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)
  • 27. Zend_Cache Algorithm: No $data = false ; $data = $cache ->get(‘myKey’); if ( false === $data ) { $data = $db ->fetchOne(...); $cache ->save( $data , ‘myKey’); } echo $data ;
  • 28. 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
  • 29. 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()
  • 30. 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
  • 31. 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)
  • 32. Zend_Log $logger = new Zend_Log(); $logger ->log(‘log this message’, Zend_Log::INFO); $logger ->info(‘log this message’);
  • 33. 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
  • 34. 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
  • 35. 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 );
  • 36. 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