Using a decorator for caching purposes
In my previous post I gave some examples on how caching can evolve. However , what annoys me in the second and third approach is that I have some extra code and dependencies which are not really related to my class. The examples bellow detail how you can use a decorator to cache another class.
class Foo { public function getExpensiveData() { return 1; } public function getNotSoExpensiveData() { return 0; } public function getUnbelievableExpensiveData($param) { //no hardware in the world can scale this sleep(1000); return 'string'; } } class Foo_Decorator_Exception extends Exception{}; class Foo_Decorator { private $source = null; public function __construct(Foo $foo) { $this->source = $foo; } public function __call($method , $args) { $tag = $method.serialize($args); $result = null; switch($method) { case 'getUnbelievableExpensiveData': case 'getExpensiveData': if ( !Cache::isCached($tag)) { Cache::save( $this->_call($method , $args),$tag ); } $result = Cache::load($tag); break; default : $result = $this->_call($method , $args); break; } return $result; } private function _call($method, $args) { if ( !is_object($this->source) ){ throw new Foo_Exception("No delegate object set"); } $delegate = $this->source; $method_variable = array($delegate, $method); $callableName = ""; if ( is_callable( $method_variable, false, $callableName )){ call_user_func_array($method_variable, $args); } else { throw new Foo_Exception("Function missing in both decorate and delegate object"); } } }
Rss
November 21st, 2009 at 3:52 pm
Good example, but I’d rather extract an interface when decorating.
November 22nd, 2009 at 12:08 am
That’s a good practice , this example only pointed how you can cache a class with the use of an decorator . With few tweaks it can be used for any class.
Of course there are other practices , but to make the example clear, this example does the job. Thank you for your feedback.
November 23rd, 2009 at 9:35 am
[...] This post was mentioned on Twitter by Flavio Luiz Mendes, deepak. deepak said: Using a decorator for caching purposes – http://www.webuml.com/blog/using-a-decorator-for-caching-purposes/62 [...]
November 23rd, 2009 at 9:39 am
[...] This post was Twitted by deepakcs [...]
November 29th, 2009 at 7:29 pm
Good solution. May want to consider using the Strategy pattern in place of the switch if the switch cases grow.
November 29th, 2009 at 7:38 pm
thanks , I’ll do that.