diff --git a/Structural/Proxy/BankAccount.php b/Structural/Proxy/BankAccount.php new file mode 100644 index 0000000..84fab34 --- /dev/null +++ b/Structural/Proxy/BankAccount.php @@ -0,0 +1,10 @@ +balance === null) { + $this->balance = parent::getBalance(); + } + + return $this->balance; + } +} diff --git a/Structural/Proxy/HeavyBankAccount.php b/Structural/Proxy/HeavyBankAccount.php new file mode 100644 index 0000000..7fd8c17 --- /dev/null +++ b/Structural/Proxy/HeavyBankAccount.php @@ -0,0 +1,25 @@ +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); + } +} diff --git a/Structural/Proxy/README.rst b/Structural/Proxy/README.rst index 554a0fc..4b3e410 100644 --- a/Structural/Proxy/README.rst +++ b/Structural/Proxy/README.rst @@ -25,15 +25,21 @@ Code You can also find this code on `GitHub`_ -Record.php +BankAccount.php -.. literalinclude:: Record.php +.. literalinclude:: BankAccount.php :language: php :linenos: -RecordProxy.php +HeavyBankAccount.php -.. literalinclude:: RecordProxy.php +.. literalinclude:: HeavyBankAccount.php + :language: php + :linenos: + +BankAccountProxy.php + +.. literalinclude:: BankAccountProxy.php :language: php :linenos: diff --git a/Structural/Proxy/Record.php b/Structural/Proxy/Record.php deleted file mode 100644 index ea018b2..0000000 --- a/Structural/Proxy/Record.php +++ /dev/null @@ -1,40 +0,0 @@ -data = $data; - } - - /** - * @param string $name - * @param string $value - */ - public function __set(string $name, string $value) - { - $this->data[$name] = $value; - } - - public function __get(string $name): string - { - if (!isset($this->data[$name])) { - throw new \OutOfRangeException('Invalid name given'); - } - - return $this->data[$name]; - } -} diff --git a/Structural/Proxy/RecordProxy.php b/Structural/Proxy/RecordProxy.php deleted file mode 100644 index 4d29ee8..0000000 --- a/Structural/Proxy/RecordProxy.php +++ /dev/null @@ -1,49 +0,0 @@ - 0) { - $this->isInitialized = true; - $this->isDirty = true; - } - } - - /** - * @param string $name - * @param string $value - */ - public function __set(string $name, string $value) - { - $this->isDirty = true; - - parent::__set($name, $value); - } - - public function isDirty(): bool - { - return $this->isDirty; - } -} diff --git a/Structural/Proxy/Tests/ProxyTest.php b/Structural/Proxy/Tests/ProxyTest.php index f2cf2f4..4e7a4a3 100644 --- a/Structural/Proxy/Tests/ProxyTest.php +++ b/Structural/Proxy/Tests/ProxyTest.php @@ -2,24 +2,23 @@ namespace DesignPatterns\Structural\Proxy\Tests; -use DesignPatterns\Structural\Proxy\RecordProxy; +use DesignPatterns\Structural\Proxy\BankAccountProxy; use PHPUnit\Framework\TestCase; class ProxyTest extends TestCase { - public function testWillSetDirtyFlagInProxy() + public function testProxyWillOnlyExecuteExpensiveGetBalanceOnce() { - $recordProxy = new RecordProxy([]); - $recordProxy->username = 'baz'; + $bankAccount = new BankAccountProxy(); + $bankAccount->deposit(30); - $this->assertTrue($recordProxy->isDirty()); - } + // this time balance is being calculated + $this->assertEquals(0, $bankAccount->getBalance()); - public function testProxyIsInstanceOfRecord() - { - $recordProxy = new RecordProxy([]); - $recordProxy->username = 'baz'; + // inheritance allows for BankAccountProxy to behave to an outsider exactly like ServerBankAccount + $bankAccount->deposit(50); - $this->assertInstanceOf(RecordProxy::class, $recordProxy); + // this time the previously calculated balance is returned again without re-calculating it + $this->assertEquals(0, $bankAccount->getBalance()); } } diff --git a/Structural/Proxy/uml/Proxy.uml b/Structural/Proxy/uml/Proxy.uml index 9b407e1..a66d877 100644 --- a/Structural/Proxy/uml/Proxy.uml +++ b/Structural/Proxy/uml/Proxy.uml @@ -1,28 +1,43 @@ - - - PHP - \DesignPatterns\Structural\Proxy\Record - - \DesignPatterns\Structural\Proxy\Record - \DesignPatterns\Structural\Proxy\RecordProxy - - - - - - - - - - - \DesignPatterns\Structural\Proxy\Record - - - Fields - Constants - Constructors - Methods - - private - - + + + PHP + \DesignPatterns\Structural\Proxy\BankAccount + + \DesignPatterns\Structural\Proxy\BankAccountProxy + \DesignPatterns\Structural\Proxy\HeavyBankAccount + \DesignPatterns\Structural\Proxy\BankAccount + + + + + + + + + + + + + + + + + + + + + + + + + + + + Fields + Constants + Constructors + Methods + + private + + diff --git a/Structural/Proxy/uml/uml.png b/Structural/Proxy/uml/uml.png index 82f548a..ef75cd6 100644 Binary files a/Structural/Proxy/uml/uml.png and b/Structural/Proxy/uml/uml.png differ diff --git a/Structural/Proxy/uml/uml.svg b/Structural/Proxy/uml/uml.svg index 1ec1d46..a2c889f 100644 --- a/Structural/Proxy/uml/uml.svg +++ b/Structural/Proxy/uml/uml.svg @@ -1,281 +1,75 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - data - - - - - - - - - - - - - __construct(data) - - - - - - - - - - - - - __set(name, value) - - - - - - - - - - __get(name) - - - - - - - - - - - - - Record - - - Record - - - - - - - - - - - - - - - - - - - isDirty - - - - - - - - - - isInitialized - - - - - - - - - - - - - __construct(data) - - - - - - - - - - - - - __set(name, value) - - - - - - - - - - - - - RecordProxy - - - RecordProxy - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +