mirror of
https://github.com/DesignPatternsPHP/DesignPatternsPHP.git
synced 2025-07-13 11:26:22 +02:00
more simple an concise example of AbstractFactory
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@ -2,7 +2,7 @@
|
|||||||
.idea
|
.idea
|
||||||
/nbproject
|
/nbproject
|
||||||
/vendor/
|
/vendor/
|
||||||
_build/
|
/_build/
|
||||||
*.mo
|
*.mo
|
||||||
.vagrant/
|
.vagrant/
|
||||||
phpunit.xml
|
phpunit.xml
|
||||||
|
@ -1,36 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace DesignPatterns\Creational\AbstractFactory;
|
|
||||||
|
|
||||||
class CsvParser implements Parser
|
|
||||||
{
|
|
||||||
const OPTION_CONTAINS_HEADER = true;
|
|
||||||
const OPTION_CONTAINS_NO_HEADER = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var bool
|
|
||||||
*/
|
|
||||||
private $skipHeaderLine;
|
|
||||||
|
|
||||||
public function __construct(bool $skipHeaderLine)
|
|
||||||
{
|
|
||||||
$this->skipHeaderLine = $skipHeaderLine;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function parse(string $input): array
|
|
||||||
{
|
|
||||||
$headerWasParsed = false;
|
|
||||||
$parsedLines = [];
|
|
||||||
|
|
||||||
foreach (explode(PHP_EOL, $input) as $line) {
|
|
||||||
if (!$headerWasParsed && $this->skipHeaderLine === self::OPTION_CONTAINS_HEADER) {
|
|
||||||
$headerWasParsed = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$parsedLines[] = str_getcsv($line);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $parsedLines;
|
|
||||||
}
|
|
||||||
}
|
|
21
Creational/AbstractFactory/DigitalProduct.php
Normal file
21
Creational/AbstractFactory/DigitalProduct.php
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace DesignPatterns\Creational\AbstractFactory;
|
||||||
|
|
||||||
|
class DigitalProduct implements Product
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
private $price;
|
||||||
|
|
||||||
|
public function __construct(int $price)
|
||||||
|
{
|
||||||
|
$this->price = $price;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function calculatePrice(): int
|
||||||
|
{
|
||||||
|
return $this->price;
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace DesignPatterns\Creational\AbstractFactory;
|
|
||||||
|
|
||||||
class JsonParser implements Parser
|
|
||||||
{
|
|
||||||
public function parse(string $input): array
|
|
||||||
{
|
|
||||||
return json_decode($input, true);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace DesignPatterns\Creational\AbstractFactory;
|
|
||||||
|
|
||||||
interface Parser
|
|
||||||
{
|
|
||||||
public function parse(string $input): array;
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace DesignPatterns\Creational\AbstractFactory;
|
|
||||||
|
|
||||||
class ParserFactory
|
|
||||||
{
|
|
||||||
public function createCsvParser(bool $skipHeaderLine): CsvParser
|
|
||||||
{
|
|
||||||
return new CsvParser($skipHeaderLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function createJsonParser(): JsonParser
|
|
||||||
{
|
|
||||||
return new JsonParser();
|
|
||||||
}
|
|
||||||
}
|
|
8
Creational/AbstractFactory/Product.php
Normal file
8
Creational/AbstractFactory/Product.php
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace DesignPatterns\Creational\AbstractFactory;
|
||||||
|
|
||||||
|
interface Product
|
||||||
|
{
|
||||||
|
public function calculatePrice(): int;
|
||||||
|
}
|
18
Creational/AbstractFactory/ProductFactory.php
Normal file
18
Creational/AbstractFactory/ProductFactory.php
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace DesignPatterns\Creational\AbstractFactory;
|
||||||
|
|
||||||
|
class ProductFactory
|
||||||
|
{
|
||||||
|
const SHIPPING_COSTS = 50;
|
||||||
|
|
||||||
|
public function createShippableProduct(int $price): Product
|
||||||
|
{
|
||||||
|
return new ShippableProduct($price, self::SHIPPING_COSTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createDigitalProduct(int $price): Product
|
||||||
|
{
|
||||||
|
return new DigitalProduct($price);
|
||||||
|
}
|
||||||
|
}
|
@ -21,27 +21,27 @@ Code
|
|||||||
|
|
||||||
You can also find this code on `GitHub`_
|
You can also find this code on `GitHub`_
|
||||||
|
|
||||||
Parser.php
|
Product.php
|
||||||
|
|
||||||
.. literalinclude:: Parser.php
|
.. literalinclude:: Product.php
|
||||||
:language: php
|
:language: php
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
CsvParser.php
|
ShippableProduct.php
|
||||||
|
|
||||||
.. literalinclude:: CsvParser.php
|
.. literalinclude:: ShippableProduct.php
|
||||||
:language: php
|
:language: php
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
JsonParser.php
|
DigitalProduct.php
|
||||||
|
|
||||||
.. literalinclude:: JsonParser.php
|
.. literalinclude:: DigitalProduct.php
|
||||||
:language: php
|
:language: php
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
ParserFactory.php
|
ProductFactory.php
|
||||||
|
|
||||||
.. literalinclude:: ParserFactory.php
|
.. literalinclude:: ProductFactory.php
|
||||||
:language: php
|
:language: php
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
|
27
Creational/AbstractFactory/ShippableProduct.php
Normal file
27
Creational/AbstractFactory/ShippableProduct.php
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace DesignPatterns\Creational\AbstractFactory;
|
||||||
|
|
||||||
|
class ShippableProduct implements Product
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var float
|
||||||
|
*/
|
||||||
|
private $productPrice;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var float
|
||||||
|
*/
|
||||||
|
private $shippingCosts;
|
||||||
|
|
||||||
|
public function __construct(int $productPrice, int $shippingCosts)
|
||||||
|
{
|
||||||
|
$this->productPrice = $productPrice;
|
||||||
|
$this->shippingCosts = $shippingCosts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function calculatePrice(): int
|
||||||
|
{
|
||||||
|
return $this->productPrice + $this->shippingCosts;
|
||||||
|
}
|
||||||
|
}
|
@ -2,59 +2,42 @@
|
|||||||
|
|
||||||
namespace DesignPatterns\Creational\AbstractFactory\Tests;
|
namespace DesignPatterns\Creational\AbstractFactory\Tests;
|
||||||
|
|
||||||
use DesignPatterns\Creational\AbstractFactory\CsvParser;
|
use DesignPatterns\Creational\AbstractFactory\DigitalProduct;
|
||||||
use DesignPatterns\Creational\AbstractFactory\JsonParser;
|
use DesignPatterns\Creational\AbstractFactory\ProductFactory;
|
||||||
use DesignPatterns\Creational\AbstractFactory\ParserFactory;
|
use DesignPatterns\Creational\AbstractFactory\ShippableProduct;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
class AbstractFactoryTest extends TestCase
|
class AbstractFactoryTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testCanCreateCsvParser()
|
public function testCanCreateDigitalProduct()
|
||||||
{
|
{
|
||||||
$factory = new ParserFactory();
|
$factory = new ProductFactory();
|
||||||
$parser = $factory->createCsvParser(CsvParser::OPTION_CONTAINS_HEADER);
|
$product = $factory->createDigitalProduct(150);
|
||||||
|
|
||||||
$this->assertInstanceOf(CsvParser::class, $parser);
|
$this->assertInstanceOf(DigitalProduct::class, $product);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCsvParserCanParse()
|
public function testCanCreateShippableProduct()
|
||||||
{
|
{
|
||||||
$factory = new ParserFactory();
|
$factory = new ProductFactory();
|
||||||
$parser = $factory->createCsvParser(CsvParser::OPTION_CONTAINS_NO_HEADER);
|
$product = $factory->createShippableProduct(150);
|
||||||
|
|
||||||
$result = $parser->parse("A0,A1,A2" . PHP_EOL . "B0,B1,B2" . PHP_EOL . "C0,C1,C2");
|
$this->assertInstanceOf(ShippableProduct::class, $product);
|
||||||
|
|
||||||
$this->assertEquals(
|
|
||||||
[
|
|
||||||
['A0', 'A1', 'A2'],
|
|
||||||
['B0', 'B1', 'B2'],
|
|
||||||
['C0', 'C1', 'C2']
|
|
||||||
],
|
|
||||||
$result
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCsvParserCanSkipHeader()
|
public function testCanCalculatePriceForDigitalProduct()
|
||||||
{
|
{
|
||||||
$factory = new ParserFactory();
|
$factory = new ProductFactory();
|
||||||
$parser = $factory->createCsvParser(CsvParser::OPTION_CONTAINS_HEADER);
|
$product = $factory->createDigitalProduct(150);
|
||||||
|
|
||||||
$result = $parser->parse("A0,A1,A2" . PHP_EOL . "B0,B1,B2" . PHP_EOL . "C0,C1,C2");
|
$this->assertEquals(150, $product->calculatePrice());
|
||||||
|
|
||||||
$this->assertEquals(
|
|
||||||
[
|
|
||||||
['B0', 'B1', 'B2'],
|
|
||||||
['C0', 'C1', 'C2']
|
|
||||||
],
|
|
||||||
$result
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCanCreateJsonParser()
|
public function testCanCalculatePriceForShippableProduct()
|
||||||
{
|
{
|
||||||
$factory = new ParserFactory();
|
$factory = new ProductFactory();
|
||||||
$parser = $factory->createJsonParser();
|
$product = $factory->createShippableProduct(150);
|
||||||
|
|
||||||
$this->assertInstanceOf(JsonParser::class, $parser);
|
$this->assertEquals(200, $product->calculatePrice());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,29 +1,29 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Diagram>
|
<Diagram>
|
||||||
<ID>PHP</ID>
|
<ID>PHP</ID>
|
||||||
<OriginalElement>\DesignPatterns\Creational\AbstractFactory\CsvParser</OriginalElement>
|
<OriginalElement>\DesignPatterns\Creational\AbstractFactory\DigitalProduct</OriginalElement>
|
||||||
<nodes>
|
<nodes>
|
||||||
<node x="116.5" y="0.0">\DesignPatterns\Creational\AbstractFactory\Parser</node>
|
<node x="0.0" y="112.0">\DesignPatterns\Creational\AbstractFactory\DigitalProduct</node>
|
||||||
<node x="0.0" y="288.0">\DesignPatterns\Creational\AbstractFactory\ParserFactory</node>
|
<node x="0.0" y="265.0">\DesignPatterns\Creational\AbstractFactory\ProductFactory</node>
|
||||||
<node x="0.0" y="146.5">\DesignPatterns\Creational\AbstractFactory\JsonParser</node>
|
<node x="204.0" y="101.0">\DesignPatterns\Creational\AbstractFactory\ShippableProduct</node>
|
||||||
<node x="168.0" y="101.0">\DesignPatterns\Creational\AbstractFactory\CsvParser</node>
|
<node x="147.5" y="0.0">\DesignPatterns\Creational\AbstractFactory\Product</node>
|
||||||
</nodes>
|
</nodes>
|
||||||
<notes />
|
<notes />
|
||||||
<edges>
|
<edges>
|
||||||
<edge source="\DesignPatterns\Creational\AbstractFactory\CsvParser" target="\DesignPatterns\Creational\AbstractFactory\Parser">
|
<edge source="\DesignPatterns\Creational\AbstractFactory\ShippableProduct" target="\DesignPatterns\Creational\AbstractFactory\Product">
|
||||||
<point x="0.0" y="-71.0" />
|
<point x="0.0" y="-59.5" />
|
||||||
<point x="307.0" y="76.0" />
|
<point x="369.0" y="76.0" />
|
||||||
<point x="227.5" y="76.0" />
|
<point x="272.0" y="76.0" />
|
||||||
<point x="37.0" y="25.5" />
|
<point x="41.5" y="25.5" />
|
||||||
</edge>
|
</edge>
|
||||||
<edge source="\DesignPatterns\Creational\AbstractFactory\JsonParser" target="\DesignPatterns\Creational\AbstractFactory\Parser">
|
<edge source="\DesignPatterns\Creational\AbstractFactory\DigitalProduct" target="\DesignPatterns\Creational\AbstractFactory\Product">
|
||||||
<point x="0.0" y="-25.5" />
|
<point x="0.0" y="-48.5" />
|
||||||
<point x="74.0" y="76.0" />
|
<point x="92.0" y="76.0" />
|
||||||
<point x="153.5" y="76.0" />
|
<point x="189.0" y="76.0" />
|
||||||
<point x="-37.0" y="25.5" />
|
<point x="-41.5" y="25.5" />
|
||||||
</edge>
|
</edge>
|
||||||
</edges>
|
</edges>
|
||||||
<settings layout="Hierarchic Group" zoom="1.0" x="107.5" y="91.0" />
|
<settings layout="Hierarchic Group" zoom="1.0" x="140.0" y="91.0" />
|
||||||
<SelectedNodes />
|
<SelectedNodes />
|
||||||
<Categories>
|
<Categories>
|
||||||
<Category>Fields</Category>
|
<Category>Fields</Category>
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 53 KiB |
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 74 KiB |
Reference in New Issue
Block a user