2.5. Dekorator (Decorator)¶
2.5.1. Przeznaczenie¶
Pozwala na dynamiczne dodawanie nowych funkcji do istniejących klas podczas działania programu.
2.5.2. Przykłady¶
- Web Service Layer: Dekorator typu JSON i XML używany w usłudze typu REST (w tym przykładzie tylko jeden z nich powinien być dozwolony).
2.5.3. Diagram UML¶

2.5.4. Kod¶
Ten kod znajdziesz również na GitHub.
Booking.php
1 2 3 4 5 6 7 8 9 10 11 12 | <?php
declare(strict_types=1);
namespace DesignPatterns\Structural\Decorator;
interface Booking
{
public function calculatePrice(): int;
public function getDescription(): string;
}
|
BookingDecorator.php
1 2 3 4 5 6 7 8 9 10 11 12 | <?php
declare(strict_types=1);
namespace DesignPatterns\Structural\Decorator;
abstract class BookingDecorator implements Booking
{
public function __construct(protected Booking $booking)
{
}
}
|
DoubleRoomBooking.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <?php
declare(strict_types=1);
namespace DesignPatterns\Structural\Decorator;
class DoubleRoomBooking implements Booking
{
public function calculatePrice(): int
{
return 40;
}
public function getDescription(): string
{
return 'double room';
}
}
|
ExtraBed.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <?php
declare(strict_types=1);
namespace DesignPatterns\Structural\Decorator;
class ExtraBed extends BookingDecorator
{
private const PRICE = 30;
public function calculatePrice(): int
{
return $this->booking->calculatePrice() + self::PRICE;
}
public function getDescription(): string
{
return $this->booking->getDescription() . ' with extra bed';
}
}
|
WiFi.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <?php
declare(strict_types=1);
namespace DesignPatterns\Structural\Decorator;
class WiFi extends BookingDecorator
{
private const PRICE = 2;
public function calculatePrice(): int
{
return $this->booking->calculatePrice() + self::PRICE;
}
public function getDescription(): string
{
return $this->booking->getDescription() . ' with wifi';
}
}
|
2.5.5. Testy¶
Tests/DecoratorTest.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 | <?php
declare(strict_types=1);
namespace DesignPatterns\Structural\Decorator\Tests;
use DesignPatterns\Structural\Decorator\DoubleRoomBooking;
use DesignPatterns\Structural\Decorator\ExtraBed;
use DesignPatterns\Structural\Decorator\WiFi;
use PHPUnit\Framework\TestCase;
class DecoratorTest extends TestCase
{
public function testCanCalculatePriceForBasicDoubleRoomBooking()
{
$booking = new DoubleRoomBooking();
$this->assertSame(40, $booking->calculatePrice());
$this->assertSame('double room', $booking->getDescription());
}
public function testCanCalculatePriceForDoubleRoomBookingWithWiFi()
{
$booking = new DoubleRoomBooking();
$booking = new WiFi($booking);
$this->assertSame(42, $booking->calculatePrice());
$this->assertSame('double room with wifi', $booking->getDescription());
}
public function testCanCalculatePriceForDoubleRoomBookingWithWiFiAndExtraBed()
{
$booking = new DoubleRoomBooking();
$booking = new WiFi($booking);
$booking = new ExtraBed($booking);
$this->assertSame(72, $booking->calculatePrice());
$this->assertSame('double room with wifi with extra bed', $booking->getDescription());
}
}
|