1.9. Strategy¶
1.9.1. Intent¶
According to the Gang of Four, the Strategy pattern is a way to “define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it” (Design Patterns: Elements of Reusable Object-Oriented Software, 2013, p. 315).
1.9.2. When to use it?¶
The Strategy pattern should be used in various cases:
- several classes differ only in their behavior (Strategy pattern lets you “attach” a behavior to a class)
- different variants of an algorithm are needed
- algorithms deal with data that should be hidden from the client
1.9.3. Diagram¶
Created using PhpStorm and yFiles.
1.9.4. Implementation¶
ExportInterface.php
1 2 3 4 5 6 7 8 9 10 11 12 | <?php
namespace Phpatterns\Behavioral\Strategy;
interface ExportInterface
{
/**
* @param string $filePath
* @return string - path of the exported file
*/
public function export($filePath);
}
|
CsvExport.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <?php
namespace Phpatterns\Behavioral\Strategy\Export;
use Phpatterns\Behavioral\Strategy;
class CsvExport implements Strategy\ExportInterface
{
/**
* @param string $filePath
* @return string - path of the exported file
*/
public function export($filePath)
{
// ...
// Do the necessary to export the file to CSV format
// ..
return 'newFile.csv';
}
}
|
PdfExport.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <?php
namespace Phpatterns\Behavioral\Strategy\Export;
use Phpatterns\Behavioral\Strategy;
class PdfExport implements Strategy\ExportInterface
{
/**
* @param string $filePath
* @return string - path of the exported file
*/
public function export($filePath)
{
// ...
// Do the necessary to export the file to PDF format
// ..
return 'newFile.pdf';
}
}
|
File.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <?php
namespace Phpatterns\Behavioral\Strategy;
class File
{
/** @var string */
private $path;
/** @param $path */
public function __construct($path)
{
$this->path = $path;
}
/**
* @param ExportInterface $exportStrategy
* @return string
*/
public function exportTo(ExportInterface $exportStrategy)
{
return $exportStrategy->export($this->path);
}
}
|
1.9.5. Tests¶
StrategyTest.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | <?php
namespace Test\Phpatterns\Behavioral\Strategy;
use Phpatterns\Behavioral\Strategy;
use Phpatterns\Behavioral\Strategy\Export;
class StrategyTest extends \PHPUnit_Framework_TestCase
{
/** @var Export\CsvExport */
private $csvStrategy;
/** @var Export\PdfExport */
private $pdfStrategy;
/** @var Strategy\File */
private $file;
protected function setUp()
{
$this->csvStrategy = new Export\CsvExport();
$this->pdfStrategy = new Export\PdfExport();
$this->file = new Strategy\File('test.txt');
}
public function testStrategyInstances()
{
$this->assertInstanceOf(Strategy\ExportInterface::class, $this->csvStrategy);
$this->assertInstanceOf(Strategy\ExportInterface::class, $this->pdfStrategy);
}
public function testCsvStrategy()
{
$this->assertSame(
'newFile.csv',
$this->file->exportTo($this->csvStrategy)
);
}
public function testPdfStrategy()
{
$this->assertSame(
'newFile.pdf',
$this->file->exportTo($this->pdfStrategy)
);
}
}
|