Purpose
The purpose of the design pattern
Create an interface to anything that is expensive or impossible to duplicate.
UML
UML design pattern diagram
Code
Code snippets
BankAccountProxy
If you have an expensive function (in the example below getBalance) we can adjust the code so that we only call the expensive function when it is really needed. You could only call the expensive method if what you need isn’t already set or it’s already in cache (just examples!).
The proxy class extends the ‘heavy' class and overrides the functionality (calling the parent instance of it when required).
The proxy class extends the ‘heavy' class and overrides the functionality (calling the parent instance of it when required).
namespace DesignPatterns\Structural\Proxy;
class BankAccountProxy extends HeavyBankAccount implements BankAccount
{
private ?int $balance = null;
public function getBalance(): int
{
// because calculating balance is so expensive,
// the usage of BankAccount::getBalance() is delayed until it really is needed
// and will not be calculated again for this instance
if ($this->balance === null) {
$this->balance = parent::getBalance();
}
return $this->balance;
}
}
BankAccount
The common interface - ensuring both classes have the same methods.
namespace DesignPatterns\Structural\Proxy;
interface BankAccount
{
public function deposit(int $amount);
public function getBalance(): int;
}
HeavyBankAccount
And finally, the expensive functionality is located here and only called when needed.
namespace DesignPatterns\Structural\Proxy;
class HeavyBankAccount implements BankAccount
{
private array $transactions = [];
public function deposit(int $amount)
{
$this->transactions[] = $amount;
}
public function getBalance(): int
{
// this is the heavy part, imagine all the transactions even from
// years and decades ago must be fetched from a database or web service
// and the balance must be calculated from it
return array_sum($this->transactions);
}
}