本文目录导读:

我来给你展示一个完整的PHP DDD(领域驱动设计)示例,这里以一个简单的订单系统为例:
领域层(Domain Layer)
值对象(Value Objects)
<?php
// Domain/ValueObject/Money.php
namespace App\Domain\ValueObject;
class Money
{
private float $amount;
private string $currency;
public function __construct(float $amount, string $currency = 'CNY')
{
if ($amount < 0) {
throw new \InvalidArgumentException('金额不能为负数');
}
$this->amount = $amount;
$this->currency = $currency;
}
public function getAmount(): float
{
return $this->amount;
}
public function getCurrency(): string
{
return $this->currency;
}
public function add(Money $money): Money
{
if ($this->currency !== $money->currency) {
throw new \InvalidArgumentException('货币不一致');
}
return new Money($this->amount + $money->amount, $this->currency);
}
public function equals(Money $money): bool
{
return $this->amount === $money->amount
&& $this->currency === $money->currency;
}
}
实体(Entities)
<?php
// Domain/Entity/Order.php
namespace App\Domain\Entity;
use App\Domain\ValueObject\Money;
use App\Domain\ValueObject\OrderStatus;
class Order
{
private string $id;
private string $customerId;
private array $items = [];
private Money $totalAmount;
private OrderStatus $status;
private \DateTimeImmutable $createdAt;
private ?\DateTimeImmutable $paidAt = null;
public function __construct(string $id, string $customerId)
{
$this->id = $id;
$this->customerId = $customerId;
$this->totalAmount = new Money(0);
$this->status = new OrderStatus(OrderStatus::PENDING);
$this->createdAt = new \DateTimeImmutable();
}
public function addItem(OrderItem $item): void
{
$this->items[] = $item;
$this->recalculateTotal();
}
public function removeItem(string $itemId): void
{
$this->items = array_filter(
$this->items,
fn(OrderItem $item) => $item->getId() !== $itemId
);
$this->recalculateTotal();
}
public function pay(): void
{
if ($this->status->getValue() !== OrderStatus::PENDING) {
throw new \DomainException('只有待支付订单才能支付');
}
if ($this->totalAmount->getAmount() <= 0) {
throw new \DomainException('订单金额必须大于0');
}
$this->status = new OrderStatus(OrderStatus::PAID);
$this->paidAt = new \DateTimeImmutable();
}
public function cancel(): void
{
if (!in_array($this->status->getValue(), [OrderStatus::PENDING, OrderStatus::PAID])) {
throw new \DomainException('当前状态不能取消');
}
$this->status = new OrderStatus(OrderStatus::CANCELLED);
}
private function recalculateTotal(): void
{
$total = new Money(0);
foreach ($this->items as $item) {
$total = $total->add($item->getSubtotal());
}
$this->totalAmount = $total;
}
// Getters...
public function getId(): string { return $this->id; }
public function getCustomerId(): string { return $this->customerId; }
public function getItems(): array { return $this->items; }
public function getTotalAmount(): Money { return $this->totalAmount; }
public function getStatus(): OrderStatus { return $this->status; }
public function getCreatedAt(): \DateTimeImmutable { return $this->createdAt; }
public function getPaidAt(): ?\DateTimeImmutable { return $this->paidAt; }
}
<?php
// Domain/Entity/OrderItem.php
namespace App\Domain\Entity;
use App\Domain\ValueObject\Money;
class OrderItem
{
private string $id;
private string $productId;
private string $productName;
private Money $price;
private int $quantity;
public function __construct(
string $id,
string $productId,
string $productName,
Money $price,
int $quantity
) {
$this->id = $id;
$this->productId = $productId;
$this->productName = $productName;
$this->price = $price;
$this->quantity = $quantity;
}
public function getSubtotal(): Money
{
return new Money($this->price->getAmount() * $this->quantity);
}
// Getters...
public function getId(): string { return $this->id; }
public function getProductId(): string { return $this->productId; }
public function getProductName(): string { return $this->productName; }
public function getPrice(): Money { return $this->price; }
public function getQuantity(): int { return $this->quantity; }
}
值对象 - 订单状态
<?php
// Domain/ValueObject/OrderStatus.php
namespace App\Domain\ValueObject;
class OrderStatus
{
public const PENDING = 'pending';
public const PAID = 'paid';
public const SHIPPED = 'shipped';
public const CANCELLED = 'cancelled';
private string $value;
private const VALID_STATUSES = [
self::PENDING,
self::PAID,
self::SHIPPED,
self::CANCELLED,
];
public function __construct(string $value)
{
if (!in_array($value, self::VALID_STATUSES)) {
throw new \InvalidArgumentException('无效的订单状态');
}
$this->value = $value;
}
public function getValue(): string
{
return $this->value;
}
public function equals(OrderStatus $status): bool
{
return $this->value === $status->getValue();
}
}
领域服务(Domain Services)
<?php
// Domain/Service/OrderPricingService.php
namespace App\Domain\Service;
use App\Domain\Entity\Order;
use App\Domain\ValueObject\Money;
class OrderPricingService
{
private const DISCOUNT_THRESHOLD = 1000;
private const DISCOUNT_RATE = 0.1; // 10% discount
public function applyDiscount(Order $order): Money
{
$total = $order->getTotalAmount();
if ($total->getAmount() >= self::DISCOUNT_THRESHOLD) {
$discountedAmount = $total->getAmount() * (1 - self::DISCOUNT_RATE);
return new Money($discountedAmount);
}
return $total;
}
}
应用层(Application Layer)
应用服务(Application Services)
<?php
// Application/Service/OrderService.php
namespace App\Application\Service;
use App\Domain\Entity\Order;
use App\Domain\Entity\OrderItem;
use App\Domain\Repository\OrderRepositoryInterface;
use App\Domain\Repository\UserRepositoryInterface;
use App\Domain\ValueObject\Money;
use App\Application\DTO\CreateOrderRequest;
use App\Application\DTO\OrderResponse;
class OrderService
{
private OrderRepositoryInterface $orderRepository;
private UserRepositoryInterface $userRepository;
public function __construct(
OrderRepositoryInterface $orderRepository,
UserRepositoryInterface $userRepository
) {
$this->orderRepository = $orderRepository;
$this->userRepository = $userRepository;
}
public function createOrder(CreateOrderRequest $request): OrderResponse
{
// 验证用户
$user = $this->userRepository->findById($request->customerId);
if (!$user) {
throw new \DomainException('用户不存在');
}
// 创建订单实体
$order = new Order(
uniqid('order_', true),
$request->customerId
);
// 添加订单项
foreach ($request->items as $item) {
$order->addItem(
new OrderItem(
uniqid('item_', true),
$item['productId'],
$item['productName'],
new Money($item['price']),
$item['quantity']
)
);
}
// 保存订单
$this->orderRepository->save($order);
return OrderResponse::fromEntity($order);
}
public function getOrder(string $orderId): OrderResponse
{
$order = $this->orderRepository->findById($orderId);
if (!$order) {
throw new \DomainException('订单不存在');
}
return OrderResponse::fromEntity($order);
}
public function payOrder(string $orderId): OrderResponse
{
$order = $this->orderRepository->findById($orderId);
if (!$order) {
throw new \DomainException('订单不存在');
}
$order->pay();
$this->orderRepository->save($order);
return OrderResponse::fromEntity($order);
}
}
DTOs(数据传输对象)
<?php
// Application/DTO/CreateOrderRequest.php
namespace App\Application\DTO;
class CreateOrderRequest
{
public string $customerId;
public array $items;
public function __construct(string $customerId, array $items)
{
$this->customerId = $customerId;
$this->items = $items;
}
}
<?php
// Application/DTO/OrderResponse.php
namespace App\Application\DTO;
use App\Domain\Entity\Order;
use App\Domain\Entity\OrderItem;
class OrderResponse
{
public string $id;
public string $customerId;
public array $items;
public float $totalAmount;
public string $status;
public string $createdAt;
public static function fromEntity(Order $order): self
{
$response = new self();
$response->id = $order->getId();
$response->customerId = $order->getCustomerId();
$response->items = array_map(
fn(OrderItem $item) => [
'id' => $item->getId(),
'productId' => $item->getProductId(),
'productName' => $item->getProductName(),
'price' => $item->getPrice()->getAmount(),
'quantity' => $item->getQuantity(),
'subtotal' => $item->getSubtotal()->getAmount()
],
$order->getItems()
);
$response->totalAmount = $order->getTotalAmount()->getAmount();
$response->status = $order->getStatus()->getValue();
$response->createdAt = $order->getCreatedAt()->format('Y-m-d H:i:s');
return $response;
}
}
基础设施层(Infrastructure Layer)
仓储实现
<?php
// Infrastructure/Repository/InMemoryOrderRepository.php
namespace App\Infrastructure\Repository;
use App\Domain\Entity\Order;
use App\Domain\Repository\OrderRepositoryInterface;
class InMemoryOrderRepository implements OrderRepositoryInterface
{
private array $orders = [];
public function save(Order $order): void
{
$this->orders[$order->getId()] = $order;
}
public function findById(string $id): ?Order
{
return $this->orders[$id] ?? null;
}
public function delete(string $id): void
{
unset($this->orders[$id]);
}
public function findAll(): array
{
return array_values($this->orders);
}
}
仓储接口
<?php
// Domain/Repository/OrderRepositoryInterface.php
namespace App\Domain\Repository;
use App\Domain\Entity\Order;
interface OrderRepositoryInterface
{
public function save(Order $order): void;
public function findById(string $id): ?Order;
public function delete(string $id): void;
public function findAll(): array;
}
使用示例
<?php
// index.php 或 Controller
use App\Application\Service\OrderService;
use App\Application\DTO\CreateOrderRequest;
use App\Infrastructure\Repository\InMemoryOrderRepository;
use App\Infrastructure\Repository\InMemoryUserRepository;
// 依赖注入设置
$orderRepository = new InMemoryOrderRepository();
$userRepository = new InMemoryUserRepository();
$orderService = new OrderService($orderRepository, $userRepository);
// 创建订单
$request = new CreateOrderRequest('user123', [
[
'productId' => 'prod1',
'productName' => 'iPhone',
'price' => 5000,
'quantity' => 1
],
[
'productId' => 'prod2',
'productName' => 'AirPods',
'price' => 1500,
'quantity' => 2
]
]);
try {
$orderResponse = $orderService->createOrder($request);
echo "订单创建成功: " . $orderResponse->id . "\n";
echo "总金额: " . $orderResponse->totalAmount . "\n";
// 支付订单
$orderResponse = $orderService->payOrder($orderResponse->id);
echo "订单支付成功,状态: " . $orderResponse->status . "\n";
} catch (\Exception $e) {
echo "错误: " . $e->getMessage() . "\n";
}
目录结构
project/
├── src/
│ ├── Domain/
│ │ ├── Entity/
│ │ │ ├── Order.php
│ │ │ └── OrderItem.php
│ │ ├── ValueObject/
│ │ │ ├── Money.php
│ │ │ └── OrderStatus.php
│ │ ├── Service/
│ │ │ └── OrderPricingService.php
│ │ └── Repository/
│ │ ├── OrderRepositoryInterface.php
│ │ └── UserRepositoryInterface.php
│ ├── Application/
│ │ ├── Service/
│ │ │ └── OrderService.php
│ │ └── DTO/
│ │ ├── CreateOrderRequest.php
│ │ └── OrderResponse.php
│ └── Infrastructure/
│ ├── Repository/
│ │ ├── InMemoryOrderRepository.php
│ │ └── InMemoryUserRepository.php
│ └── Database/
│ └── (数据库相关类)
└── index.php
这个示例展示了DDD的核心概念:
- 值对象:Money、OrderStatus
- 实体:Order、OrderItem
- 领域服务:OrderPricingService
- 应用服务:OrderService
- 仓储接口与实现:OrderRepositoryInterface
- DTO:CreateOrderRequest、OrderResponse
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播