From 58797a30661efc843d369c7aadbcef160bfac00f Mon Sep 17 00:00:00 2001 From: Robert Podwika Date: Fri, 10 Jul 2015 21:00:28 +0200 Subject: [PATCH] Decorator pattern and some fixes --- readme.md | 4 +- src/Behavioral/Memento/readme.md | 2 +- src/Structural/Decorator/Character.php | 66 +++++++++++++++++++ src/Structural/Decorator/IDecoratedAttack.php | 36 ++++++++++ .../Decorator/ShootingCharacter.php | 60 +++++++++++++++++ src/Structural/Decorator/readme.md | 16 +++++ tests/DecoratorTest.php | 44 +++++++++++++ tests/SingletonTest.php | 9 +++ 8 files changed, 235 insertions(+), 2 deletions(-) create mode 100644 src/Structural/Decorator/Character.php create mode 100644 src/Structural/Decorator/IDecoratedAttack.php create mode 100644 src/Structural/Decorator/ShootingCharacter.php create mode 100644 src/Structural/Decorator/readme.md create mode 100644 tests/DecoratorTest.php diff --git a/readme.md b/readme.md index 1dde0ce..4cd2dd1 100644 --- a/readme.md +++ b/readme.md @@ -17,4 +17,6 @@ pull request or message me * [Observer](src/Behavioral/Observer) * [Strategy](src/Behavioral/Strategy) 3. Creational - * [Factory](src/Creational/Factory) \ No newline at end of file + * [Factory](src/Creational/Factory) +4. Structural + * [Decorator](src/Structural/Decorator) \ No newline at end of file diff --git a/src/Behavioral/Memento/readme.md b/src/Behavioral/Memento/readme.md index a570db9..4cf02ac 100644 --- a/src/Behavioral/Memento/readme.md +++ b/src/Behavioral/Memento/readme.md @@ -8,7 +8,7 @@ in PHP the easiest way is Serialisation with magic methods *__wakeup()* and *__s You should use memento if you want revert state of object. It can be used in transactional operations. Memento protects object encapsulation. -#How to use +##How to use See [tests/SimpleBasketTest](/tests/SimpleBasketTest.php) diff --git a/src/Structural/Decorator/Character.php b/src/Structural/Decorator/Character.php new file mode 100644 index 0000000..84647f6 --- /dev/null +++ b/src/Structural/Decorator/Character.php @@ -0,0 +1,66 @@ +setHp($hp); + } + + /** + * @inheritdoc + */ + public function getHp() + { + return $this->hp; + } + + /** + * @inheritdoc + */ + public function setHp($amount) + { + $this->hp = $amount; + + return $this; + } + + /** + * @inheritdoc + */ + public function attack(Character $victim) + { + $victim->weaken(self::DEFAULT_ATTACK_HP); + + return $this; + } + + /** + * @inheritdoc + */ + public function weaken($amount) + { + $this->hp -= $amount; + + return $this->hp <= 0 ? 'dead' : 'alive'; + } + + +} \ No newline at end of file diff --git a/src/Structural/Decorator/IDecoratedAttack.php b/src/Structural/Decorator/IDecoratedAttack.php new file mode 100644 index 0000000..0df645e --- /dev/null +++ b/src/Structural/Decorator/IDecoratedAttack.php @@ -0,0 +1,36 @@ +character = $character; + } + + /** + * @inheritdoc + */ + public function attack(Character $victim) + { + //shoots target + $victim->weaken(self::SHOOT_ATTACK_HP); + //performs default attack as well + $this->character->attack($victim); + return $this; + } + + /** + * @inheritdoc + */ + public function getHp() + { + return $this->character->getHp(); + } + + /** + * @inheritdoc + */ + public function setHp($amount) + { + $this->character->setHp($amount); + + return $this; + } + + /** + * @inheritdoc + */ + public function weaken($amount) + { + return $this->character->weaken($amount); + } +} \ No newline at end of file diff --git a/src/Structural/Decorator/readme.md b/src/Structural/Decorator/readme.md new file mode 100644 index 0000000..4cf16b3 --- /dev/null +++ b/src/Structural/Decorator/readme.md @@ -0,0 +1,16 @@ +#Decorator pattern + +Decorator is used to add/remove functionality to object without modifying it. Decorator is very useful for adhering +Single Responsibility Principle in SOLID because it allows functionality to be divided amoung classes with uniques areas +of concern. + +Decorator can be used to add behavior to class statically or dynamically. + +##When to use + +1. When you want to add/remove class behavior without modifying it. +2. When you want to wrap some object with additional functionality. + +##How to use + +See [tests/DecoratorTest](/tests/DecoratorTest.php) \ No newline at end of file diff --git a/tests/DecoratorTest.php b/tests/DecoratorTest.php new file mode 100644 index 0000000..2a56caf --- /dev/null +++ b/tests/DecoratorTest.php @@ -0,0 +1,44 @@ +assertEquals(100, $murderer->getHp()); + $this->assertEquals(90, $victim->getHp()); + $murderer->weaken(10); + $this->assertEquals(90, $murderer->getHp()); + } + + /** + * @covers \Rpodwika\Designpatterns\Structural\Decorator\ShootingCharacter + */ + public function testShootingCharacter() + { + $victim = new Character(); + $murderer = new Character(); + + $shootingMurderer = new ShootingCharacter($murderer); + $this->assertEquals($murderer->getHp(), $shootingMurderer->getHp()); + $shootingMurderer->attack($victim); + $this->assertEquals(75, $victim->getHp()); + $murderer->attack($victim); + $this->assertEquals(70, $victim->getHp()); + + } +} diff --git a/tests/SingletonTest.php b/tests/SingletonTest.php index 6f18393..4ba9e12 100755 --- a/tests/SingletonTest.php +++ b/tests/SingletonTest.php @@ -12,6 +12,9 @@ class SingletonTest extends PHPUnit_Framework_TestCase { + /** + * @covers \Rpodwika\Designpatterns\Antipatterns\Singleton + */ public function testSingletonReturnsObject() { $singletonObject = Singleton::getInstance(); @@ -20,11 +23,17 @@ public function testSingletonReturnsObject() $this->assertInstanceOf('Rpodwika\Designpatterns\Antipatterns\Singleton', $singletonObject); } + /** + * @covers \Rpodwika\Designpatterns\Antipatterns\Singleton + */ public function testDoSomethingReturnsProperObject() { $this->assertEquals('I do something', Singleton::getInstance()->doSomething()); } + /** + * @covers \Rpodwika\Designpatterns\Antipatterns\SingletonTrait + */ public function testSingletonTrait() { $object = SingletonSample::getInstance();