mirror of
https://github.com/DesignPatternsPHP/DesignPatternsPHP.git
synced 2025-05-05 05:58:08 +02:00
PHP7 TemplateMethod
This commit is contained in:
parent
36f3df8fbb
commit
19fff0aed9
@ -2,16 +2,10 @@
|
||||
|
||||
namespace DesignPatterns\Behavioral\TemplateMethod;
|
||||
|
||||
/**
|
||||
* BeachJourney is vacation at the beach.
|
||||
*/
|
||||
class BeachJourney extends Journey
|
||||
{
|
||||
/**
|
||||
* prints what to do to enjoy your vacation.
|
||||
*/
|
||||
protected function enjoyVacation()
|
||||
protected function enjoyVacation(): string
|
||||
{
|
||||
echo "Swimming and sun-bathing\n";
|
||||
return "Swimming and sun-bathing";
|
||||
}
|
||||
}
|
||||
|
@ -2,16 +2,15 @@
|
||||
|
||||
namespace DesignPatterns\Behavioral\TemplateMethod;
|
||||
|
||||
/**
|
||||
* CityJourney is a journey in a city.
|
||||
*/
|
||||
class CityJourney extends Journey
|
||||
{
|
||||
/**
|
||||
* prints what to do in your journey to enjoy vacation.
|
||||
*/
|
||||
protected function enjoyVacation()
|
||||
protected function enjoyVacation(): string
|
||||
{
|
||||
echo "Eat, drink, take photos and sleep\n";
|
||||
return "Eat, drink, take photos and sleep";
|
||||
}
|
||||
|
||||
protected function buyGift(): string
|
||||
{
|
||||
return "Buy a gift";
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,11 @@ namespace DesignPatterns\Behavioral\TemplateMethod;
|
||||
|
||||
abstract class Journey
|
||||
{
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private $thingsToDo = [];
|
||||
|
||||
/**
|
||||
* This is the public service provided by this class and its subclasses.
|
||||
* Notice it is final to "freeze" the global behavior of algorithm.
|
||||
@ -12,46 +17,49 @@ abstract class Journey
|
||||
*/
|
||||
final public function takeATrip()
|
||||
{
|
||||
$this->buyAFlight();
|
||||
$this->takePlane();
|
||||
$this->enjoyVacation();
|
||||
$this->buyGift();
|
||||
$this->takePlane();
|
||||
$this->thingsToDo[] = $this->buyAFlight();
|
||||
$this->thingsToDo[] = $this->takePlane();
|
||||
$this->thingsToDo[] = $this->enjoyVacation();
|
||||
$buyGift = $this->buyGift();
|
||||
|
||||
if ($buyGift !== null) {
|
||||
$this->thingsToDo[] = $buyGift;
|
||||
}
|
||||
|
||||
$this->thingsToDo[] = $this->takePlane();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method must be implemented, this is the key-feature of this pattern.
|
||||
*/
|
||||
abstract protected function enjoyVacation();
|
||||
abstract protected function enjoyVacation(): string;
|
||||
|
||||
/**
|
||||
* This method is also part of the algorithm but it is optional.
|
||||
* This is an "adapter" (do not confuse with the Adapter pattern, not related)
|
||||
* You can override it only if you need to.
|
||||
* You can override it only if you need to
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
protected function buyGift()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
private function buyAFlight(): string
|
||||
{
|
||||
return 'Buy a flight ticket';
|
||||
}
|
||||
|
||||
private function takePlane(): string
|
||||
{
|
||||
return 'Taking the plane';
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will be unknown by subclasses (better).
|
||||
* @return string[]
|
||||
*/
|
||||
private function buyAFlight()
|
||||
public function getThingsToDo(): array
|
||||
{
|
||||
echo "Buying a flight\n";
|
||||
return $this->thingsToDo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses will get access to this method but cannot override it and
|
||||
* compromise this algorithm (warning : cause of cyclic dependencies).
|
||||
*/
|
||||
final protected function takePlane()
|
||||
{
|
||||
echo "Taking the plane\n";
|
||||
}
|
||||
|
||||
// A note regarding the keyword "final" : don't use it when you start coding :
|
||||
// add it after you narrow and know exactly what change and what remain unchanged
|
||||
// in this algorithm.
|
||||
// [abstract] x [3 access] x [final] = 12 combinations, it can be hard !
|
||||
}
|
||||
|
@ -4,40 +4,33 @@ namespace DesignPatterns\Behavioral\TemplateMethod\Tests;
|
||||
|
||||
use DesignPatterns\Behavioral\TemplateMethod;
|
||||
|
||||
/**
|
||||
* JourneyTest tests all journeys.
|
||||
*/
|
||||
class JourneyTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testBeach()
|
||||
public function testCanGetOnVacationOnTheBeach()
|
||||
{
|
||||
$journey = new TemplateMethod\BeachJourney();
|
||||
$this->expectOutputRegex('#sun-bathing#');
|
||||
$journey->takeATrip();
|
||||
$beachJourney = new TemplateMethod\BeachJourney();
|
||||
$beachJourney->takeATrip();
|
||||
|
||||
$this->assertEquals(
|
||||
['Buy a flight ticket', 'Taking the plane', 'Swimming and sun-bathing', 'Taking the plane'],
|
||||
$beachJourney->getThingsToDo()
|
||||
);
|
||||
}
|
||||
|
||||
public function testCity()
|
||||
public function testCanGetOnAJourneyToACity()
|
||||
{
|
||||
$journey = new TemplateMethod\CityJourney();
|
||||
$this->expectOutputRegex('#drink#');
|
||||
$journey->takeATrip();
|
||||
}
|
||||
$beachJourney = new TemplateMethod\CityJourney();
|
||||
$beachJourney->takeATrip();
|
||||
|
||||
/**
|
||||
* How to test an abstract template method with PHPUnit.
|
||||
*/
|
||||
public function testLasVegas()
|
||||
{
|
||||
$journey = $this->getMockForAbstractClass('DesignPatterns\Behavioral\TemplateMethod\Journey');
|
||||
$journey->expects($this->once())
|
||||
->method('enjoyVacation')
|
||||
->will($this->returnCallback(array($this, 'mockUpVacation')));
|
||||
$this->expectOutputRegex('#Las Vegas#');
|
||||
$journey->takeATrip();
|
||||
}
|
||||
|
||||
public function mockUpVacation()
|
||||
{
|
||||
echo "Fear and loathing in Las Vegas\n";
|
||||
$this->assertEquals(
|
||||
[
|
||||
'Buy a flight ticket',
|
||||
'Taking the plane',
|
||||
'Eat, drink, take photos and sleep',
|
||||
'Buy a gift',
|
||||
'Taking the plane'
|
||||
],
|
||||
$beachJourney->getThingsToDo()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,35 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Diagram>
|
||||
<ID>PHP</ID>
|
||||
<OriginalElement>\DesignPatterns\Behavioral\TemplateMethod\BeachJourney</OriginalElement>
|
||||
<nodes>
|
||||
<node x="152.0" y="177.0">\DesignPatterns\Behavioral\TemplateMethod\CityJourney</node>
|
||||
<node x="47.0" y="0.0">\DesignPatterns\Behavioral\TemplateMethod\Journey</node>
|
||||
<node x="0.0" y="177.0">\DesignPatterns\Behavioral\TemplateMethod\BeachJourney</node>
|
||||
</nodes>
|
||||
<notes />
|
||||
<edges>
|
||||
<edge source="\DesignPatterns\Behavioral\TemplateMethod\CityJourney" target="\DesignPatterns\Behavioral\TemplateMethod\Journey">
|
||||
<point x="0.0" y="-23.5" />
|
||||
<point x="218.0" y="152.0" />
|
||||
<point x="189.5" y="152.0" />
|
||||
<point x="47.5" y="63.5" />
|
||||
</edge>
|
||||
<edge source="\DesignPatterns\Behavioral\TemplateMethod\BeachJourney" target="\DesignPatterns\Behavioral\TemplateMethod\Journey">
|
||||
<point x="0.0" y="-23.5" />
|
||||
<point x="66.0" y="152.0" />
|
||||
<point x="94.5" y="152.0" />
|
||||
<point x="-47.5" y="63.5" />
|
||||
</edge>
|
||||
</edges>
|
||||
<settings layout="Hierarchic Group" zoom="1.0" x="142.0" y="112.0" />
|
||||
<SelectedNodes />
|
||||
<Categories>
|
||||
<Category>Fields</Category>
|
||||
<Category>Constants</Category>
|
||||
<Category>Constructors</Category>
|
||||
<Category>Methods</Category>
|
||||
</Categories>
|
||||
<VISIBILITY>private</VISIBILITY>
|
||||
</Diagram>
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Diagram>
|
||||
<ID>PHP</ID>
|
||||
<OriginalElement>\DesignPatterns\Behavioral\TemplateMethod\BeachJourney</OriginalElement>
|
||||
<nodes>
|
||||
<node x="-18.0" y="234.0">\DesignPatterns\Behavioral\TemplateMethod\BeachJourney</node>
|
||||
<node x="13.0" y="-3.0">\DesignPatterns\Behavioral\TemplateMethod\Journey</node>
|
||||
<node x="151.0" y="234.0">\DesignPatterns\Behavioral\TemplateMethod\CityJourney</node>
|
||||
</nodes>
|
||||
<notes />
|
||||
<edges>
|
||||
<edge source="\DesignPatterns\Behavioral\TemplateMethod\BeachJourney" target="\DesignPatterns\Behavioral\TemplateMethod\Journey">
|
||||
<point x="0.0" y="-23.5" />
|
||||
<point x="66.0" y="152.0" />
|
||||
<point x="94.5" y="152.0" />
|
||||
<point x="-47.5" y="63.5" />
|
||||
</edge>
|
||||
<edge source="\DesignPatterns\Behavioral\TemplateMethod\CityJourney" target="\DesignPatterns\Behavioral\TemplateMethod\Journey">
|
||||
<point x="0.0" y="-23.5" />
|
||||
<point x="218.0" y="152.0" />
|
||||
<point x="189.5" y="152.0" />
|
||||
<point x="47.5" y="63.5" />
|
||||
</edge>
|
||||
</edges>
|
||||
<settings layout="Hierarchic Group" zoom="1.0" x="142.0" y="112.0" />
|
||||
<SelectedNodes />
|
||||
<Categories>
|
||||
<Category>Fields</Category>
|
||||
<Category>Constants</Category>
|
||||
<Category>Constructors</Category>
|
||||
<Category>Methods</Category>
|
||||
</Categories>
|
||||
<VISIBILITY>private</VISIBILITY>
|
||||
</Diagram>
|
||||
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 46 KiB |
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 107 KiB |
Loading…
x
Reference in New Issue
Block a user