Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 购物情境建模_Oop_Design Patterns_Domain Driven Design_Modeling_Cqrs - Fatal编程技术网

Oop 购物情境建模

Oop 购物情境建模,oop,design-patterns,domain-driven-design,modeling,cqrs,Oop,Design Patterns,Domain Driven Design,Modeling,Cqrs,我想以DDD的方式编写我的第一个应用程序(电子商务),我想知道我是否一切正常,所以我想知道你对我的建模的意见-如何改进,我应该寻找什么等。每一个反馈都将非常感谢 我已经将我的应用程序划分为几个有界上下文(目录、购物、订购),下面的示例基于购物上下文。我也在尝试使用CQRS(因此AddProductToCart命令) 我的业务要求如下: 客户应该能够将产品添加到他的购物车中 添加产品的价格应针对用户,并基于以下几个因素:(全球折扣、用户折扣和客户国家(一些国家降低了基准价格) 我认识了以下参与

我想以DDD的方式编写我的第一个应用程序(电子商务),我想知道我是否一切正常,所以我想知道你对我的建模的意见-如何改进,我应该寻找什么等。每一个反馈都将非常感谢

我已经将我的应用程序划分为几个有界上下文(目录、购物、订购),下面的示例基于购物上下文。我也在尝试使用CQRS(因此
AddProductToCart
命令)

我的业务要求如下:

  • 客户应该能够将产品添加到他的购物车中
  • 添加产品的价格应针对用户,并基于以下几个因素:(全球折扣、用户折扣和客户国家(一些国家降低了基准价格)
我认识了以下参与者(请注意对方法和类的评论):

/**
*具有唯一购物车的客户(聚合根)
*/
类客户
{
/**
*@var int
*/
私人$customerId;
/**
*@var字符串
*/
私人$国家;
/**
*@var-Cart
*/
私人$cart;
/**
*@var PriceProvider
*/
私人供应商;
/**
*以用户特定的价格将产品添加到客户购物车
*
*@param$productId
*@returncartline
*/
公共函数addProductToCart($productId)
{
$price=$this->priceProvider->priceForProduct($productId,$this->customerId,$this->country);
返回$this->cart->addLine($productId,$price);
}
}
/**
*用于持久化目的的简单CartLine对象
*/
类CartLine
{
公共$productId;
公帑(元);;
公费$cartId;
函数构造($cartId,$productId,$price)
{
$this->cartId=$cartId;
$this->price=$price;
$this->productId=$productId;
}
}
班车
{
私人$cartId;
公共函数addLine($productId,$price)
{
返回新的CartLine($this->cartId,$productId,$price);
}
}
/**
*提供特定国家/地区的价格
*/
类价格提供者
{
产品的公共函数价格($productId、$userId、$country)
{
//为客户确定产品价格的逻辑
//基于可用的全球折扣、用户折扣和国家/地区
}
}
/**
*用于将产品添加到购物车的命令
*/
类AddProductToCart
{
public$customerId;
公共$productId;
}
/**
*将所有内容绑定在一起的应用程序服务
*/
类客户服务
{
公共函数addProductToCart(addProductToCart$命令)
{
/**@var Customer$Customer*/
$customer=$this->customerRepository->customerfid($command->customerId);
$cartLine=$customer->addProductToCart($command->productId);
$this->cartLineRepository->save($cartLine);
}
}

这是一种正确的方法吗?我是否违反了DDD原则?我可以改进一些东西吗?

CQRS通常涉及命令处理程序
命令与“命令式”动词相关联。
CustomerService
过于宽泛,因此不代表“命令”的意图

我将通过
AddProductToCart
更改
CustomerService

class AddProductToCart
{
    public function handle(AddProductToCartCommand $command) {
      ...
    }
}
顺便说一句,通过将您的各种功能拆分为适当的命令,您可以在需要时为一个特定命令制作多个版本。

因此,以稀疏顺序排列(部分取决于编程语言):

  • 您的聚合根应该被显式标记(例如使用IAggregateRoot接口),因此如果您的语言支持泛型,那么您只能实现聚合根的存储库
  • 您的构造函数应始终是私有的,请改用factory。仅在初始化问题上使用构造函数。在下一个将来,
    客户的构建规则可能会增加复杂性,factory将允许您灵活使用
  • 不变逻辑是域逻辑。依赖于用例的逻辑是应用程序逻辑(即,
    PriceProvide
    r与域逻辑无关)

您也需要一个事件:AddProductToCartCommand-->ProductAddedToCartte即使只是出于好奇,这是一个学习应用程序还是一个生产应用程序?@Sudarshan,它最终可能会成为一个小型生产应用程序。;)您为什么要问这个问题?我应该换点什么吗?你说得对,我应该在那里用一个处理程序。我假设这个处理程序应该是域的一部分,而不是应用层?应用层,它仍然像一个应用程序service@acid您应该阅读以下内容:甚至有一个完整的CQR处理命令处理程序的示例(代码)。如何确定哪些规则应用于哪些产品以确定其价格,而不是域逻辑?也许它不应该驻留在这个AR中(但如果不是,那么在哪里?),但对我来说,这绝对是一个域层。