Skip to content

Commit d8450d7

Browse files
committed
add classes of composite pattern
1 parent c613d77 commit d8450d7

File tree

4 files changed

+129
-0
lines changed

4 files changed

+129
-0
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Growthdev\DesignPatterns\Structural\Composite;
6+
7+
use BadMethodCallException;
8+
9+
abstract class CatalogComponent
10+
{
11+
protected function add(CatalogComponent $catalogComponent): void
12+
{
13+
throw new BadMethodCallException('Method not implemented');
14+
}
15+
16+
protected function remove(CatalogComponent $catalogComponent): void
17+
{
18+
throw new BadMethodCallException('Method not implemented');
19+
}
20+
21+
protected function getChild(CatalogComponent $catalogComponent): CatalogComponent
22+
{
23+
throw new BadMethodCallException('Method not implemented');
24+
}
25+
26+
abstract protected function display(): void;
27+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Growthdev\DesignPatterns\Structural\Composite;
6+
7+
final class Product extends CatalogComponent
8+
{
9+
public readonly string $name;
10+
public readonly float $price;
11+
12+
public function __construct(string $name, float $price)
13+
{
14+
$this->name = $name;
15+
$this->price = $price;
16+
}
17+
18+
public function display(): void
19+
{
20+
printf("Product: %s R$ %.2f\n", $this->name, $this->price);
21+
}
22+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Growthdev\DesignPatterns\Structural\Composite;
6+
7+
use SplObjectStorage;
8+
9+
final class ProductCatalog extends CatalogComponent
10+
{
11+
private SplObjectStorage $products;
12+
13+
public function __construct(private string $name)
14+
{
15+
$this->products = new SplObjectStorage();
16+
}
17+
18+
public function add(CatalogComponent $catalogComponent): void
19+
{
20+
$this->products->attach($catalogComponent);
21+
}
22+
23+
public function remove(CatalogComponent $catalogComponent): void
24+
{
25+
$this->products->detach($catalogComponent);
26+
}
27+
28+
public function getChild(CatalogComponent $catalogComponent): CatalogComponent
29+
{
30+
if (!$this->products->contains($catalogComponent)) {
31+
throw new \InvalidArgumentException('CatalogComponent not found');
32+
}
33+
return $catalogComponent;
34+
}
35+
36+
public function display(): void
37+
{
38+
echo "Catalog: {$this->name}\n";
39+
foreach ($this->products as $product) {
40+
$product->display();
41+
}
42+
}
43+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Growthdev\DesignPatterns\Tests\Structural\Composite;
6+
7+
use Growthdev\DesignPatterns\Structural\Composite\Product;
8+
use Growthdev\DesignPatterns\Structural\Composite\ProductCatalog;
9+
use PHPUnit\Framework\TestCase;
10+
11+
final class CompositeTest extends TestCase
12+
{
13+
public function testCanCreateProductCatalog(): void
14+
{
15+
$catalog = new ProductCatalog('Catalog 1');
16+
$catalog2 = new ProductCatalog('Catalog 2');
17+
18+
$catalog->add(new Product('Product 1', 10.0));
19+
$catalog->add(new Product('Product 2', 20.0));
20+
$catalog->add($catalog2);
21+
$catalog->getChild($catalog2)->add(new Product('Product 3', 30.0));
22+
$catalog->getChild($catalog2)->add(new Product('Product 4', 40.0));
23+
$catalog->getChild($catalog2)->add(new Product('Product 5', 50.0));
24+
25+
$catalog->display();
26+
27+
$this->expectOutputString(
28+
"Catalog: Catalog 1\n" .
29+
"Product: Product 1 R$ 10.00\n" .
30+
"Product: Product 2 R$ 20.00\n" .
31+
"Catalog: Catalog 2\n" .
32+
"Product: Product 3 R$ 30.00\n" .
33+
"Product: Product 4 R$ 40.00\n" .
34+
"Product: Product 5 R$ 50.00\n"
35+
);
36+
}
37+
}

0 commit comments

Comments
 (0)