Shopping context modelling
我想以DDD方式编写我的第一个应用程序(电子商务),我想知道我是否做对了所有事情,所以我希望您对我的建模有何看法-如何改进它,应该怎么做?我正在寻找等。每一个反馈将不胜感激。
我已将我的应用程序划分为几个有界上下文(目录,购物,订购),下面的示例基于购物环境。我也尝试使用CQRS(因此
我的业务要求如下:
- 客户应该能够将产品添加到他的购物车中
- 附加产品的价格应特定于用户,并应基于以下几个因素:(全球折扣,用户折扣和客户所在的国家/地区(某些国家/地区降低了基本价格)
我认识以下演员(请注意方法和类的注释):
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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | /** * A customer (Aggregate Root) having an unique cart */ class Customer { /** * @var int */ private $customerId; /** * @var string */ private $country; /** * @var Cart */ private $cart; /** * @var PriceProvider */ private $priceProvider; /** * Adds product to customers cart with user-specific price * * @param $productId * @return CartLine */ public function addProductToCart($productId) { $price = $this->priceProvider->priceForProduct($productId, $this->customerId, $this->country); return $this->cart->addLine($productId, $price); } } /** * Simple CartLine object for persisting purposes */ class CartLine { public $productId; public $price; public $cartId; function __construct($cartId, $productId, $price) { $this->cartId = $cartId; $this->price = $price; $this->productId = $productId; } } class Cart { private $cartId; public function addLine($productId, $price) { return new CartLine($this->cartId, $productId, $price); } } /** * Provides price for specific country */ class PriceProvider { public function priceForProduct($productId, $userId, $country) { // Logic for determining product price for customer // Based on available global discounts, user discounts and country } } /** * Command for adding product to cart */ class AddProductToCart { public $customerId; public $productId; } /** * An application service to bind everything together */ class CustomerService { public function addProductToCart(AddProductToCart $command) { /** @var Customer $customer */ $customer = $this->customerRepository->customerOfId($command->customerId); $cartLine = $customer->addProductToCart($command->productId); $this->cartLineRepository->save($cartLine); } } |
这是正确的方法吗?我在这里违反任何DDD原则吗?我可以改善吗?
CQRS通常涉及命令处理程序。
命令与"命令式"动词相关联。
我将
1 2 3 4 5 6 | class AddProductToCart { public function handle(AddProductToCartCommand $command) { ... } } |
通过将所有各种功能拆分为适当的命令,您将能够根据需要为一个特定命令制作多个版本。
所以稀疏顺序(部分取决于编程语言):
- 您的聚合根目录应进行显式标记(例如,使用IAggregateRoot接口),因此,如果您的语言支持通用语言,则只能实现聚合根目录的存储库。
-
您的构造函数应始终是私有的,而应使用工厂。仅将构造函数用于初始化问题。在您的下一个未来中,
Customer 的构造规则可能会增加复杂性,而工厂将为您提供灵活性。 -
不变逻辑是域逻辑。取决于用例的逻辑是应用逻辑(即
PriceProvide r与域逻辑无关)