2.5. Decorator

    • Zend Framework: decorators for instances
    • Web Service Layer: Decorators JSON and XML for a REST service (inthis case, only one of these should be allowed of course)

    You can also find this code on GitHub

    BookingDecorator.php

    1. <?php
    2.  
    3. namespace DesignPatterns\Structural\Decorator;
    4.  
    5. abstract class BookingDecorator implements Booking
    6. {
    7. /**
    8. * @var Booking
    9. */
    10. protected $booking;
    11.  
    12. public function __construct(Booking $booking)
    13. {
    14. $this->booking = $booking;
    15. }
    16. }

    DoubleRoomBooking.php

    1. <?php
    2.  
    3.  
    4. class ExtraBed extends BookingDecorator
    5. {
    6. private const PRICE = 30;
    7.  
    8. public function calculatePrice(): int
    9. {
    10. return $this->booking->calculatePrice() + self::PRICE;
    11. }
    12.  
    13. public function getDescription(): string
    14. {
    15. return $this->booking->getDescription() . ' with extra bed';
    16. }
    17. }

    WiFi.php

    Tests/DecoratorTest.php

    1. <?php
    2.  
    3. namespace DesignPatterns\Structural\Decorator\Tests;
    4.  
    5. use DesignPatterns\Structural\Decorator\DoubleRoomBooking;
    6. use DesignPatterns\Structural\Decorator\ExtraBed;
    7. use DesignPatterns\Structural\Decorator\WiFi;
    8. use PHPUnit\Framework\TestCase;
    9.  
    10. class DecoratorTest extends TestCase
    11. public function testCanCalculatePriceForBasicDoubleRoomBooking()
    12. {
    13. $booking = new DoubleRoomBooking();
    14.  
    15. $this->assertEquals(40, $booking->calculatePrice());
    16. $this->assertEquals('double room', $booking->getDescription());
    17. }
    18.  
    19. public function testCanCalculatePriceForDoubleRoomBookingWithWiFi()
    20. {
    21. $booking = new DoubleRoomBooking();
    22. $booking = new WiFi($booking);
    23.  
    24. $this->assertEquals(42, $booking->calculatePrice());
    25. $this->assertEquals('double room with wifi', $booking->getDescription());
    26. }
    27.  
    28. public function testCanCalculatePriceForDoubleRoomBookingWithWiFiAndExtraBed()
    29. {
    30. $booking = new DoubleRoomBooking();
    31. $booking = new WiFi($booking);
    32. $booking = new ExtraBed($booking);
    33.  
    34. $this->assertEquals(72, $booking->calculatePrice());
    35. $this->assertEquals('double room with wifi with extra bed', $booking->getDescription());
    36. }