2.10. Proxy

2.10.1. Purpose

To interface to anything that is expensive or impossible to duplicate.

2.10.2. Examples

  • Doctrine2 uses proxies to implement framework magic (e.g. lazyinitialization) in them, while the user still works with his ownentity classes and will never use nor touch the proxies

2.10.3. UML Diagram

Alt Proxy UML Diagram

2.10.4. Code

You can also find this code on GitHub

BankAccount.php

  1. <?php
  2.  
  3. namespace DesignPatterns\Structural\Proxy;
  4.  
  5. interface BankAccount
  6. {
  7. public function deposit(int $amount);
  8.  
  9. public function getBalance(): int;
  10. }

HeavyBankAccount.php

  1. <?php
  2.  
  3. namespace DesignPatterns\Structural\Proxy;
  4.  
  5. class HeavyBankAccount implements BankAccount
  6. {
  7. /**
  8. * @var int[]
  9. */
  10. private $transactions = [];
  11.  
  12. public function deposit(int $amount)
  13. {
  14. $this->transactions[] = $amount;
  15. }
  16.  
  17. public function getBalance(): int
  18. {
  19. // this is the heavy part, imagine all the transactions even from
  20. // years and decades ago must be fetched from a database or web service
  21. // and the balance must be calculated from it
  22.  
  23. return array_sum($this->transactions);
  24. }
  25. }

BankAccountProxy.php

  1. <?php
  2.  
  3. namespace DesignPatterns\Structural\Proxy;
  4.  
  5. class BankAccountProxy extends HeavyBankAccount implements BankAccount
  6. {
  7. /**
  8. * @var int
  9. */
  10. private $balance;
  11.  
  12. public function getBalance(): int
  13. {
  14. // because calculating balance is so expensive,
  15. // the usage of BankAccount::getBalance() is delayed until it really is needed
  16. // and will not be calculated again for this instance
  17.  
  18. if ($this->balance === null) {
  19. $this->balance = parent::getBalance();
  20. }
  21.  
  22. return $this->balance;
  23. }
  24. }

2.10.5. Test