SlideShare a Scribd company logo
1 of 27
Patterns:  - Decorator .  - Composite. Diego Lewin Senior Developer at Netconcepts
Structural Patterns  are Design Patterns that ease the design by identifying  a simple way to realize relationships between entities. * Adapter pattern. * Aggregate pattern. * Bridge pattern. * Composite pattern. *  Decorator pattern. * Extensibility pattern. * Facade pattern. * Flyweight pattern. * Proxy pattern. * Pipes and filters. * Private class data pattern. Structural Patterns
The Decorator Pattern ,[object Object]
The Problem ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
The ”Classes” get_price()‏ is_available()‏ Product Customer_Review get_custom_reviews()‏ Tag_Cloud get_arr_tag_cloud()‏ Integration_MYOB do_integration()‏ Custom_Funtionality is_available()‏
Customer_Review Tag_Cloud Custom_Funtionality Integration_MYOB get_custom_reviews()‏ get_arr_tag_cloud()‏ do_integration()‏ get_price()‏ is_available()‏ is_available()‏ How many extensions are TOO many? Product
class Product { public function get_price(); public function is_available(); } class Integration_MYOB  extends  Product { public function do_integration()‏ { ....... } ......... } class Tag_Cloud extends  Integration_MYOB { public function get_arr_tag_cloud()‏ { ....... } ......... } Some Code...
class Customer_Review extends  Tag_Cloud   { public function get_arr_customer_review()‏ { ....... } ......... } class Custom_Functionality extends  Customer_Review { public function is_available()‏ { ....... } ......... } More Code....
Product Customer_Review Tag_Cloud Custom_Funtionality Integration_MYOB get_custom_reviews()‏ get_arr_tag_cloud()‏ do_integration()‏ do_integration()‏ is_available()‏ is_available()‏ Category But, not all the projects need the same functionality... I need to change my Code..,  Class  EXPLOSION
Customer_Review_For_Product get_arr_custom_review()‏ Category Product do_integration()‏ is_available()‏ Customer_Review_For_Category get_arr_custom_review()‏ Tag_Cloud_For_Product get_arr_tag_cloud()‏ Tag_Cloud_For_Category get_arr_tag_cloud()‏ Even, there is more... I should reuse my extended classes !! get_arr_product()‏
What, if we ”extend” the class  in a 'run time' dynamically. Magic !! Example : /* *instantiation * we pass in the constructor, the object that we want to extend.. (decorate)‏ */ $obj_decorated_product  =  new Customer_Review(new Custom_Functionality( new Product)); /* * calling 'decorated' methods, the final reslut  is the same as we extend the classes */ $arr_custom_review  = $obj_decorated_product->get_arr_custom_review(); $is_available  = $obj_decorated_product->is_available(); The Decorator comes to save us !
Example 2: //instantiation, with 4 decoratros $obj_decorated_product = new Integration_MYOB( new Tag_Cloud( new Customer_Review(new Custom_Functionality( new Product)))); //calling 'decorated' methods $arr_custom_review  = $obj_decorated_product->get_arr_custom_review(); $is_available  = $obj_decorated_product->is_available(); $arr_tag_cloud  = $obj_decorated_product->get_arr_tag_cloud(); Example 3: //instantiation, 'decorating' a product object and a category object with the same 'decorators' $obj_decorated_product  = new Tag_Cloud( new Customer_Review( new Product)); $obj_decorated_category  = new Tag_Cloud( new Customer_Review( new Category)); More Examples !
//All the decorators have to  extend  the  Abstract_Decorator  class class Customer_Review_Decorator  extends Abstract_Decorator { public function get_arr_customer_review()‏ { //insted of using  parent:: , we need to use  $this->object_decorated $entity_id = $this->object_decorated->id; ............ ............ return ......; } } class Custom_Functionality_Decorator  extends Abstract_Decorator { public function is_available()‏ { //insted of using  parent:: , we need to use  $this->object_decorated   $is_available = $this->object_decorated->is_available(); ............ ............ return ......; } } Concrete Decorators
Customer_Review Tag_Cloud Custom_Funtionality Integration_MYOB get_custom_reviews()‏ get_arr_tag_cloud()‏ do_integration()‏ is_available()‏ __call()‏ __get()‏ __set()‏ UML Diagram (PHP 5 !)‏ obj_decorated Product get_price()‏ is_available()‏ Decorator
abstract class Abstract_Decorator { /** * It is the object that we are decorating * and we must set it in the contructor */ protected $obj_decorated; public function __construct( $obj_decorated )‏ { $this->obj_decorated = $obj_decorated; } /** * If a function is not found in this class the call * came here and we forward to the $this->obj_decorated object */ protected function __call($method,$arguments)‏ { return call_user_func_array(array(&$this->obj_decorated, $method),$arguments); } /** * If a parameter that we are trying to read is not found in this class the call * came here and we forward to the $this->obj_decorated object */ protected function __get($property_name)‏ { return $this->obj_decorated->$property_name; } /** * If a parameter that we are tring to write is not found in this class the call * came here and we forward to the $this->obj_decorated object */ protected function __set($property_name, $property_value)‏ { return $this->obj_decorated->$property_name = $property_value; }
get_price()‏ is_available()‏ discount_brand get_amount()‏ discount_category get_amount()‏ discount_buy_get get_amount()‏ discount_highest_price get_amount()‏ discount_custom get_amount()‏ Product
Refactoring Diary Composite Pattern
Discount calculations. Class Product { public function get_price()‏ { $price =... //now we apply the discounts $obj_discount_brand  = new Discount_Brand($this->id,$qty); $price -= $obj_discount_brand->get_brand_discount(); $obj_discount_category  = new Discount_Category(); $obj_discount_category->set_product_id($this->id); $obj_discount_category->set_qty($qty); $price -= $obj_discount_category->get_discount(); $obj_discount_highest_price = new Discount_Highest_Price($this->id,$qty); $price -= $obj_discount_category->get_amount(); $obj_discount_buy_get = new Discount_Buy_Get; $obj_discount_custom1 = new Discount_Custom1; $obj_discount_custom1 = new Discount_Customer_Big_Clients_EEUU; $obj_discount_custom1 = new Discount_Customer_EEUU; $obj_discount_custom1 = new Discount_Customer_NZ; return $price; } }
Class Product  { public function get_price() { $price =... //now we apply the discounts $obj_discount_brand  = new Discount_Brand(); $obj_discount_brand->set_product_id($this->id)‏ $obj_discount_brand->set_qty($this->qty)‏ $price -= $obj_discount_brand->get_amount(); $obj_discount_category  = new Discount_Category(); $obj_discount_category->set_product_id($this->id)‏ $obj_discount_category->set_qty($this->qty)‏ $price -= $obj_discount_category->get_amount(); $obj_discount_highest_price = new Discount_Highest_Price(); ............ ............... ............. return $price; } } A Commun Interface for the Discount classes and..what if the discounts have a commun interface...
[object Object],[object Object],[object Object],[object Object],[object Object],Open for extension, but closed for modification
Class Product { public function get_price()‏ { $price =...; $obj_discount = new Discount_Composite; $obj_discount->set_product_id($product->id); $obj_discount->set_qty($product->qty); $price -=$obj_discount->get_amount(); return $price } } We are still using the same interface for the discount class, that we were using for each strategy: ->set_product_id($id)‏ ->set_qty(qty)‏ ->get_amount()‏ The new 'stable' Product class Decoupling the Discount from the Product class
Decoupling the Discount from the Product class class Discount { public function __constructor( )‏ { $this->_arr_obj_discount_strategy  array(new Discount_ Brand,new Discount_Category, new...)‏ } public function set_id ($id)‏ { foreach($this->_arr_obj_discount_strategy as &$obj_discount_strategy)‏ { $obj_discount_strategy->set_id ($id); } } public function set_qty ($qty)‏ { foreach($this->_arr_obj_discount_strategy as &$obj_discount_strategy)‏ { $obj_discount_strategy->set_qty ($qty); } } public function  get_amount()‏ { foreach($this->_arr_obj_discount_strategy as $obj_discount_strategy)‏ { $amount += $obj_discount_strategy-> get_amount(); } return $amount; } }
class Discount_Composite { public function  add_strategy($obj_strategy)‏ { $this->_arr_obj_discount_strategy[]=  $obj_strategy; } public function  set_id($id)‏ { foreach($this->_arr_obj_discount_strategy as &$obj_discount_strategy)‏ { $obj_discount_strategy->set_id ($id); } } public function  set_qty($qty)‏ { foreach($this->_arr_obj_discount_strategy as &$obj_discount_strategy)‏ { $obj_discount_strategy->set_qty ($qty); } } public function  get_amount()‏ { foreach($this->_arr_obj_discount_strategy as $obj_discount_strategy)‏ { $amount += $obj_discount_strategy-> get_amount(); } return $amount; } } Compose objects into tree structures to represent whole-part hierarchies.  Composite lets clients treat individual objects and compositions of objects uniformly. [GoF, p163]  The discount composite class
Class Product_Controller  { public function product()‏ { .................... .................... $obj_discount = new Discount_Composite $obj_discount->add_strategy(new Discount_Brand); $obj_discount->add_strategy(new Discount_Category); .................... .................... $obj_product->set_obj_discount($obj_discount); } } Class Product_Controller  { public function product()‏ { .................... .................... $obj_discount = new Discount_Brand; .................... .................... $obj_product->set_obj_discount($obj_discount); } }
Class Product_Controller  { public function product()‏ { .................... .................... $obj_discount_composite = new Discount_Composite $obj_discount_composite->add_strategy( new Discount_Brand); $obj_discount_composite->add_strategy( newDiscount_Category); .................... .................... if(is_object($obj_customer))‏ { $obj_discount_composite_customer = new Discount_Composite $obj_discount_composite_customer->add_strategy('Discount_Seniors'); $obj_discount_composite_customer->add_strategy('Discount_Students'); } $obj_discount_composite->add_strategy($obj_discount_composite_customer); $obj_discount_composite->get_amount($obj_product ->get_id(),$obj_product ->get_qty()); } }
Discount_Interface set_product_id()‏ set_qty()‏ get_amount()‏ Discount_Composite add_strategy()‏ remove_strategy()‏ Concrete_Discount Compose objects into tree structures to represent whole-part hierarchies.  Composite lets clients treat individual objects and compositions of objects uniformly. [GoF, p163]
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]

More Related Content

What's hot

Steps for variant configuration and pricing
Steps for variant configuration and pricingSteps for variant configuration and pricing
Steps for variant configuration and pricing
Mohit2385
 
Meet Magento Belarus debug Pavel Novitsky (eng)
Meet Magento Belarus debug Pavel Novitsky (eng)Meet Magento Belarus debug Pavel Novitsky (eng)
Meet Magento Belarus debug Pavel Novitsky (eng)
Pavel Novitsky
 
Google app engine cheat sheet
Google app engine cheat sheetGoogle app engine cheat sheet
Google app engine cheat sheet
Piyush Mittal
 
Doctrator Symfony Live 2011 San Francisco
Doctrator Symfony Live 2011 San FranciscoDoctrator Symfony Live 2011 San Francisco
Doctrator Symfony Live 2011 San Francisco
pablodip
 

What's hot (18)

Best Practices for Magento Debugging
Best Practices for Magento Debugging Best Practices for Magento Debugging
Best Practices for Magento Debugging
 
TDC 2015 - Metaprogramação na prática
TDC 2015 - Metaprogramação na práticaTDC 2015 - Metaprogramação na prática
TDC 2015 - Metaprogramação na prática
 
Testing survival Guide
Testing survival GuideTesting survival Guide
Testing survival Guide
 
Editing the Visual Editor (WordPress)
Editing the Visual Editor (WordPress)Editing the Visual Editor (WordPress)
Editing the Visual Editor (WordPress)
 
How to Mess Up Your Angular UI Components
How to Mess Up Your Angular UI ComponentsHow to Mess Up Your Angular UI Components
How to Mess Up Your Angular UI Components
 
Steps for variant configuration and pricing
Steps for variant configuration and pricingSteps for variant configuration and pricing
Steps for variant configuration and pricing
 
Fixing Magento Core for Better Performance - Ivan Chepurnyi
Fixing Magento Core for Better Performance - Ivan ChepurnyiFixing Magento Core for Better Performance - Ivan Chepurnyi
Fixing Magento Core for Better Performance - Ivan Chepurnyi
 
[PHP] Zend_Db (Zend Framework)
[PHP] Zend_Db (Zend Framework)[PHP] Zend_Db (Zend Framework)
[PHP] Zend_Db (Zend Framework)
 
Meet Magento Belarus debug Pavel Novitsky (eng)
Meet Magento Belarus debug Pavel Novitsky (eng)Meet Magento Belarus debug Pavel Novitsky (eng)
Meet Magento Belarus debug Pavel Novitsky (eng)
 
Refactoring
RefactoringRefactoring
Refactoring
 
Google app engine cheat sheet
Google app engine cheat sheetGoogle app engine cheat sheet
Google app engine cheat sheet
 
Custom AngularJS Directives
Custom AngularJS DirectivesCustom AngularJS Directives
Custom AngularJS Directives
 
Doctrator Symfony Live 2011 San Francisco
Doctrator Symfony Live 2011 San FranciscoDoctrator Symfony Live 2011 San Francisco
Doctrator Symfony Live 2011 San Francisco
 
I regret nothing
I regret nothingI regret nothing
I regret nothing
 
PyCon KR 2018 Effective Tips for Django ORM in Practice
PyCon KR 2018 Effective Tips for Django ORM in PracticePyCon KR 2018 Effective Tips for Django ORM in Practice
PyCon KR 2018 Effective Tips for Django ORM in Practice
 
AngularJS custom directive
AngularJS custom directiveAngularJS custom directive
AngularJS custom directive
 
Test driven development_for_php
Test driven development_for_phpTest driven development_for_php
Test driven development_for_php
 
Effective Android Data Binding
Effective Android Data BindingEffective Android Data Binding
Effective Android Data Binding
 

Similar to Patterns in PHP

Magento Imagine eCommerce Conference 2011: Using Magento's Import Module
Magento Imagine eCommerce Conference 2011: Using Magento's Import ModuleMagento Imagine eCommerce Conference 2011: Using Magento's Import Module
Magento Imagine eCommerce Conference 2011: Using Magento's Import Module
varien
 
Magento's Imagine eCommerce Conference 2011 - Import Export in a Flash with t...
Magento's Imagine eCommerce Conference 2011 - Import Export in a Flash with t...Magento's Imagine eCommerce Conference 2011 - Import Export in a Flash with t...
Magento's Imagine eCommerce Conference 2011 - Import Export in a Flash with t...
MagentoImagine
 
Making Magento flying like a rocket! (A set of valuable tips for developers)
Making Magento flying like a rocket! (A set of valuable tips for developers)Making Magento flying like a rocket! (A set of valuable tips for developers)
Making Magento flying like a rocket! (A set of valuable tips for developers)
Ivan Chepurnyi
 
OOPS IN PHP.pptx
OOPS IN PHP.pptxOOPS IN PHP.pptx
OOPS IN PHP.pptx
rani marri
 
Dependency injection in Drupal 8
Dependency injection in Drupal 8Dependency injection in Drupal 8
Dependency injection in Drupal 8
Alexei Gorobets
 
03 Object Relational Mapping
03 Object Relational Mapping03 Object Relational Mapping
03 Object Relational Mapping
Ranjan Kumar
 

Similar to Patterns in PHP (20)

PHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better CodePHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better Code
 
Magento Indexes
Magento IndexesMagento Indexes
Magento Indexes
 
Magento Imagine eCommerce Conference 2011: Using Magento's Import Module
Magento Imagine eCommerce Conference 2011: Using Magento's Import ModuleMagento Imagine eCommerce Conference 2011: Using Magento's Import Module
Magento Imagine eCommerce Conference 2011: Using Magento's Import Module
 
Magento's Imagine eCommerce Conference 2011 - Import Export in a Flash with t...
Magento's Imagine eCommerce Conference 2011 - Import Export in a Flash with t...Magento's Imagine eCommerce Conference 2011 - Import Export in a Flash with t...
Magento's Imagine eCommerce Conference 2011 - Import Export in a Flash with t...
 
Key Insights into Development Design Patterns for Magento 2 - Magento Live UK
Key Insights into Development Design Patterns for Magento 2 - Magento Live UKKey Insights into Development Design Patterns for Magento 2 - Magento Live UK
Key Insights into Development Design Patterns for Magento 2 - Magento Live UK
 
Oops concepts in php
Oops concepts in phpOops concepts in php
Oops concepts in php
 
Making Magento flying like a rocket! (A set of valuable tips for developers)
Making Magento flying like a rocket! (A set of valuable tips for developers)Making Magento flying like a rocket! (A set of valuable tips for developers)
Making Magento flying like a rocket! (A set of valuable tips for developers)
 
Solid angular
Solid angularSolid angular
Solid angular
 
Why is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosWhy is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenarios
 
Laravel Design Patterns
Laravel Design PatternsLaravel Design Patterns
Laravel Design Patterns
 
OOPS IN PHP.pptx
OOPS IN PHP.pptxOOPS IN PHP.pptx
OOPS IN PHP.pptx
 
Django design-patterns
Django design-patternsDjango design-patterns
Django design-patterns
 
Oop php 5
Oop php 5Oop php 5
Oop php 5
 
Dependency injection in Drupal 8
Dependency injection in Drupal 8Dependency injection in Drupal 8
Dependency injection in Drupal 8
 
Facade Design Pattern
Facade Design PatternFacade Design Pattern
Facade Design Pattern
 
Design Patterns and Usage
Design Patterns and UsageDesign Patterns and Usage
Design Patterns and Usage
 
10 PHP Design Patterns #burningkeyboards
10 PHP Design Patterns #burningkeyboards10 PHP Design Patterns #burningkeyboards
10 PHP Design Patterns #burningkeyboards
 
Curso Symfony - Clase 2
Curso Symfony - Clase 2Curso Symfony - Clase 2
Curso Symfony - Clase 2
 
03 Object Relational Mapping
03 Object Relational Mapping03 Object Relational Mapping
03 Object Relational Mapping
 
PHP OOP Lecture - 02.pptx
PHP OOP Lecture - 02.pptxPHP OOP Lecture - 02.pptx
PHP OOP Lecture - 02.pptx
 

Recently uploaded

Recently uploaded (20)

Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 

Patterns in PHP

  • 1. Patterns: - Decorator . - Composite. Diego Lewin Senior Developer at Netconcepts
  • 2. Structural Patterns are Design Patterns that ease the design by identifying a simple way to realize relationships between entities. * Adapter pattern. * Aggregate pattern. * Bridge pattern. * Composite pattern. * Decorator pattern. * Extensibility pattern. * Facade pattern. * Flyweight pattern. * Proxy pattern. * Pipes and filters. * Private class data pattern. Structural Patterns
  • 3.
  • 4.
  • 5. The ”Classes” get_price()‏ is_available()‏ Product Customer_Review get_custom_reviews()‏ Tag_Cloud get_arr_tag_cloud()‏ Integration_MYOB do_integration()‏ Custom_Funtionality is_available()‏
  • 6. Customer_Review Tag_Cloud Custom_Funtionality Integration_MYOB get_custom_reviews()‏ get_arr_tag_cloud()‏ do_integration()‏ get_price()‏ is_available()‏ is_available()‏ How many extensions are TOO many? Product
  • 7. class Product { public function get_price(); public function is_available(); } class Integration_MYOB extends Product { public function do_integration()‏ { ....... } ......... } class Tag_Cloud extends Integration_MYOB { public function get_arr_tag_cloud()‏ { ....... } ......... } Some Code...
  • 8. class Customer_Review extends Tag_Cloud { public function get_arr_customer_review()‏ { ....... } ......... } class Custom_Functionality extends Customer_Review { public function is_available()‏ { ....... } ......... } More Code....
  • 9. Product Customer_Review Tag_Cloud Custom_Funtionality Integration_MYOB get_custom_reviews()‏ get_arr_tag_cloud()‏ do_integration()‏ do_integration()‏ is_available()‏ is_available()‏ Category But, not all the projects need the same functionality... I need to change my Code.., Class EXPLOSION
  • 10. Customer_Review_For_Product get_arr_custom_review()‏ Category Product do_integration()‏ is_available()‏ Customer_Review_For_Category get_arr_custom_review()‏ Tag_Cloud_For_Product get_arr_tag_cloud()‏ Tag_Cloud_For_Category get_arr_tag_cloud()‏ Even, there is more... I should reuse my extended classes !! get_arr_product()‏
  • 11. What, if we ”extend” the class in a 'run time' dynamically. Magic !! Example : /* *instantiation * we pass in the constructor, the object that we want to extend.. (decorate)‏ */ $obj_decorated_product = new Customer_Review(new Custom_Functionality( new Product)); /* * calling 'decorated' methods, the final reslut is the same as we extend the classes */ $arr_custom_review = $obj_decorated_product->get_arr_custom_review(); $is_available = $obj_decorated_product->is_available(); The Decorator comes to save us !
  • 12. Example 2: //instantiation, with 4 decoratros $obj_decorated_product = new Integration_MYOB( new Tag_Cloud( new Customer_Review(new Custom_Functionality( new Product)))); //calling 'decorated' methods $arr_custom_review = $obj_decorated_product->get_arr_custom_review(); $is_available = $obj_decorated_product->is_available(); $arr_tag_cloud = $obj_decorated_product->get_arr_tag_cloud(); Example 3: //instantiation, 'decorating' a product object and a category object with the same 'decorators' $obj_decorated_product = new Tag_Cloud( new Customer_Review( new Product)); $obj_decorated_category = new Tag_Cloud( new Customer_Review( new Category)); More Examples !
  • 13. //All the decorators have to extend the Abstract_Decorator class class Customer_Review_Decorator extends Abstract_Decorator { public function get_arr_customer_review()‏ { //insted of using parent:: , we need to use $this->object_decorated $entity_id = $this->object_decorated->id; ............ ............ return ......; } } class Custom_Functionality_Decorator extends Abstract_Decorator { public function is_available()‏ { //insted of using parent:: , we need to use $this->object_decorated $is_available = $this->object_decorated->is_available(); ............ ............ return ......; } } Concrete Decorators
  • 14. Customer_Review Tag_Cloud Custom_Funtionality Integration_MYOB get_custom_reviews()‏ get_arr_tag_cloud()‏ do_integration()‏ is_available()‏ __call()‏ __get()‏ __set()‏ UML Diagram (PHP 5 !)‏ obj_decorated Product get_price()‏ is_available()‏ Decorator
  • 15. abstract class Abstract_Decorator { /** * It is the object that we are decorating * and we must set it in the contructor */ protected $obj_decorated; public function __construct( $obj_decorated )‏ { $this->obj_decorated = $obj_decorated; } /** * If a function is not found in this class the call * came here and we forward to the $this->obj_decorated object */ protected function __call($method,$arguments)‏ { return call_user_func_array(array(&$this->obj_decorated, $method),$arguments); } /** * If a parameter that we are trying to read is not found in this class the call * came here and we forward to the $this->obj_decorated object */ protected function __get($property_name)‏ { return $this->obj_decorated->$property_name; } /** * If a parameter that we are tring to write is not found in this class the call * came here and we forward to the $this->obj_decorated object */ protected function __set($property_name, $property_value)‏ { return $this->obj_decorated->$property_name = $property_value; }
  • 16. get_price()‏ is_available()‏ discount_brand get_amount()‏ discount_category get_amount()‏ discount_buy_get get_amount()‏ discount_highest_price get_amount()‏ discount_custom get_amount()‏ Product
  • 18. Discount calculations. Class Product { public function get_price()‏ { $price =... //now we apply the discounts $obj_discount_brand = new Discount_Brand($this->id,$qty); $price -= $obj_discount_brand->get_brand_discount(); $obj_discount_category = new Discount_Category(); $obj_discount_category->set_product_id($this->id); $obj_discount_category->set_qty($qty); $price -= $obj_discount_category->get_discount(); $obj_discount_highest_price = new Discount_Highest_Price($this->id,$qty); $price -= $obj_discount_category->get_amount(); $obj_discount_buy_get = new Discount_Buy_Get; $obj_discount_custom1 = new Discount_Custom1; $obj_discount_custom1 = new Discount_Customer_Big_Clients_EEUU; $obj_discount_custom1 = new Discount_Customer_EEUU; $obj_discount_custom1 = new Discount_Customer_NZ; return $price; } }
  • 19. Class Product { public function get_price() { $price =... //now we apply the discounts $obj_discount_brand = new Discount_Brand(); $obj_discount_brand->set_product_id($this->id)‏ $obj_discount_brand->set_qty($this->qty)‏ $price -= $obj_discount_brand->get_amount(); $obj_discount_category = new Discount_Category(); $obj_discount_category->set_product_id($this->id)‏ $obj_discount_category->set_qty($this->qty)‏ $price -= $obj_discount_category->get_amount(); $obj_discount_highest_price = new Discount_Highest_Price(); ............ ............... ............. return $price; } } A Commun Interface for the Discount classes and..what if the discounts have a commun interface...
  • 20.
  • 21. Class Product { public function get_price()‏ { $price =...; $obj_discount = new Discount_Composite; $obj_discount->set_product_id($product->id); $obj_discount->set_qty($product->qty); $price -=$obj_discount->get_amount(); return $price } } We are still using the same interface for the discount class, that we were using for each strategy: ->set_product_id($id)‏ ->set_qty(qty)‏ ->get_amount()‏ The new 'stable' Product class Decoupling the Discount from the Product class
  • 22. Decoupling the Discount from the Product class class Discount { public function __constructor( )‏ { $this->_arr_obj_discount_strategy array(new Discount_ Brand,new Discount_Category, new...)‏ } public function set_id ($id)‏ { foreach($this->_arr_obj_discount_strategy as &$obj_discount_strategy)‏ { $obj_discount_strategy->set_id ($id); } } public function set_qty ($qty)‏ { foreach($this->_arr_obj_discount_strategy as &$obj_discount_strategy)‏ { $obj_discount_strategy->set_qty ($qty); } } public function get_amount()‏ { foreach($this->_arr_obj_discount_strategy as $obj_discount_strategy)‏ { $amount += $obj_discount_strategy-> get_amount(); } return $amount; } }
  • 23. class Discount_Composite { public function add_strategy($obj_strategy)‏ { $this->_arr_obj_discount_strategy[]= $obj_strategy; } public function set_id($id)‏ { foreach($this->_arr_obj_discount_strategy as &$obj_discount_strategy)‏ { $obj_discount_strategy->set_id ($id); } } public function set_qty($qty)‏ { foreach($this->_arr_obj_discount_strategy as &$obj_discount_strategy)‏ { $obj_discount_strategy->set_qty ($qty); } } public function get_amount()‏ { foreach($this->_arr_obj_discount_strategy as $obj_discount_strategy)‏ { $amount += $obj_discount_strategy-> get_amount(); } return $amount; } } Compose objects into tree structures to represent whole-part hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly. [GoF, p163] The discount composite class
  • 24. Class Product_Controller { public function product()‏ { .................... .................... $obj_discount = new Discount_Composite $obj_discount->add_strategy(new Discount_Brand); $obj_discount->add_strategy(new Discount_Category); .................... .................... $obj_product->set_obj_discount($obj_discount); } } Class Product_Controller { public function product()‏ { .................... .................... $obj_discount = new Discount_Brand; .................... .................... $obj_product->set_obj_discount($obj_discount); } }
  • 25. Class Product_Controller { public function product()‏ { .................... .................... $obj_discount_composite = new Discount_Composite $obj_discount_composite->add_strategy( new Discount_Brand); $obj_discount_composite->add_strategy( newDiscount_Category); .................... .................... if(is_object($obj_customer))‏ { $obj_discount_composite_customer = new Discount_Composite $obj_discount_composite_customer->add_strategy('Discount_Seniors'); $obj_discount_composite_customer->add_strategy('Discount_Students'); } $obj_discount_composite->add_strategy($obj_discount_composite_customer); $obj_discount_composite->get_amount($obj_product ->get_id(),$obj_product ->get_qty()); } }
  • 26. Discount_Interface set_product_id()‏ set_qty()‏ get_amount()‏ Discount_Composite add_strategy()‏ remove_strategy()‏ Concrete_Discount Compose objects into tree structures to represent whole-part hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly. [GoF, p163]
  • 27.