动态地为类的实例添加功能
Booking.php
<?php declare(strict_types=1); namespace DesignPatternsStructuralDecorator; interface Booking { public function calculatePrice(): int; public function getDescription(): string; }
BookingDecorator.php
<?php declare(strict_types=1); namespace DesignPatternsStructuralDecorator; abstract class BookingDecorator implements Booking { public function __construct(protected Booking $booking) { } }
DoubleRoomBooking.php
<?php declare(strict_types=1); namespace DesignPatternsStructuralDecorator; class DoubleRoomBooking implements Booking { public function calculatePrice(): int { return 40; } public function getDescription(): string { return "double room"; } }
ExtraBed.php
<?php declare(strict_types=1); namespace DesignPatternsStructuralDecorator; 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
<?php declare(strict_types=1); namespace DesignPatternsStructuralDecorator; 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"; } }
Tests/DecoratorTest.php
<?php declare(strict_types=1); namespace DesignPatternsStructuralDecoratorTests; use DesignPatternsStructuralDecoratorDoubleRoomBooking; use DesignPatternsStructuralDecoratorExtraBed; use DesignPatternsStructuralDecoratorWiFi; use PHPUnitFrameworkTestCase; 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()); } }
UML 交互图概述:UML 交互图描述的是对象之间的动态合作关系以及合作过程中的行为次序。UML 交互图常常用来描述一个用例的行为,...
在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。 在策略模式中...
拦截过滤器模式(Intercepting Filter Pattern)用于对应用程序的请求或响应做一些预处理/后处理。定义过滤器,并在把请求传给实...
OceanBase Connector/J 的语句池功能允许应用程序以与使用 Connection 对象相同的方式重用PreparedStatement对象。多个逻辑...
Web3VanillaJavascript入门项目这是一个简单的应用程序登录用户,在Moralis数据库中创建用户配置文件并将用户事务同步到Moralis...