我将我的值Object Item作为组件映射到下面的映射配置
{
Table("Product");
Not.LazyLoad();
Id(x => x.Id, "id");
Map(x => x.Number, "number");
Map(x => x.Name, "name");
Map(x => x.Description, "description");
Map(x => x.Status, "status");
HasMany(x => x.ItemLines).Component(
m =>
{
m.Map(x => x.ItemId, "itemid");
m.Map(x => x.Qty, "quantity");
}).Table("productitems").KeyColumn("itemid");
}
Class structure
public class ItemLine
{
public Product Product { get; set; }
public Guid ItemId { get; set; }
public int Qty { get; set; }
public ItemLine()
{
}
public ItemLine(Product product, Guid itemId, int qty)
{ …Run Code Online (Sandbox Code Playgroud) nhibernate nhibernate-mapping fluent-nhibernate value-objects
知道值对象表示域的描述,该描述可以是不同有界上下文中的许多实体的一部分.例如,FullName值对象,此VO可以作为Customer实体的成员存在于"book aquisition"上下文中,也可以作为BookAuthor实体的成员存在于"book book"上下文中.知道值对象可以在域的不同部分使用,应该在哪里实现值对象?他们是否应该有一个特殊的层/模块,每个有界的上下文将在需要时使用?
标题中的问题可能不太清楚,让我解释一下:
在我的模型中,我有一个Person,它有一个Address.但是,许多人可以共享相同的地址.
当我定义我的模型时,我假设Person是一个实体,但是如果你改变了Address的一个属性,那么就是一个Value-Object,那么它就不再是同一个地址了.
由于多个人可以共享一个地址,如果我直接进入数据库实现,并天真地假设该人有一些address_xxxx字段,它不会在数据库中生成太多的重复项吗?那个人有一个与地址表相关的address_id字段不是更好吗?如果是这样,那么地址是实体权利吗?
事件源域模型中是否有值对象的位置?
让我们将值对象定义为具有不可变状态的对象,它保护其不变量并且没有特定的标识符。
在这种情况下,事件源域模型是完全或部分事件源的域,这意味着它的当前状态可以通过应用过去发生的所有事件来派生。事件本身被认为是不可变的,即使随着时间的推移也是如此。
关于在事件中使用值对象的有效性已经发生了争论- 这个问题稍微更进一步:值对象在事件源域中是否有一席之地?
使用值对象的(潜在)问题是,以收紧不变量的方式改变域变得相当棘手。
此场景的一个示例是拥有一个Username值对象,唯一的限制是名称必须介于 2 到 16 个字符之间。
虽然这种方法已经运行良好一段时间了,但该企业决定只允许使用至少 5 个字符的用户名。迁移期开始,名称少于 5 个字符的用户将被要求更新其名称。
可以说这个过程是成功的,纠正事件被应用,每个人都很高兴。我们收紧了对值对象的限制,Username要求至少 5 个字符。
有一段时间每个人都很高兴,但后来我们发现快照有问题并重播所有事件。
现在,我们的Username对象面临一个异常:通过加载历史数据,我们破坏了域的不变量。
值对象的规则具有追溯力- 这是否使它们本质上不适合事件溯源?是否值得应用值对象的版本控制?有没有更简单的方法来避免此类问题?
我一直在研究DDD的一个小项目.我到处都看到Value Objects是不可变的,因此,你无法修改它.只有实体.
我将使用每个人都使用的示例.地址.假设Address是 Customer实体的VO(也是根聚合).如果用户更新了他的地址,这在任何购物车场景中都有效,那么我该怎么做?我必须修改该VO地址,以便我将其保存到数据库中.意思是,这个VO必须以某种方式具有身份,以便我在数据库中识别它.除非NHibernate使用映射来处理它,对吧.你不是LinqToSql的情况.或者我想我必须创建一个新的聚合,其中地址是一个实体而不是?然后几乎有一个地址的副本我需要在我的聚合中的地址吗?
然而.我仍然无法包装整个Entity/VO概念.在我看来,就像在数据库中有表示的所有东西一样,即使你在模型中使用它作为VO,它也是某种实体,因为为了让你坚持它,你需要某种KEY来在数据库中识别它.
在一天结束时,所有Value Objects的数据都来自数据库(主要是).所以我仍然无法理解在数据更新的情况下如何使它们不可变.
经过两个月的激烈阅读,我发现整个DDD是一个巨大的矛盾问题.阅读所有这些博客,你会看到我在说什么.不幸的是,那里有ZERO演示应用程序,您可以将其用作角色模型或指导.它们都受到开发人员偏好的影响.然后他们最终攻击对方的博客.隔夜-DDD-Guru的博客真的有助于整个社区的混乱.
谢谢你的光临.期待进行建设性的讨论.
我刚刚读到有关值对象的内容,它是不可变的,描述为:
一个简单的小对象,例如金钱或日期范围,其相等性不基于身份。
看看我当前现有的实体,我想我可以将几乎所有不是实体的东西都变成值对象。
假设我有一个实体类 User。
class User
{
public $id;
public $firstname;
public $lastname;
public $email;
}
Run Code Online (Sandbox Code Playgroud)
我可以让它由值对象Id、FirstName、LastName和组成,因为这些Email属性相等性Password都不User是基于身份的,对吧?但话又说回来,我可能会更进一步,制作更多的 VO Int、、String(由和VOName组成)等。FirstNameLastName
我应该在哪里划定界限以防止过度设计?
一个域包含这么多 VO 正常吗?
我对价值对象的理解是否正确?
在构建一个值对象时,我有一个简单的问题,该值对象中具有特定类型的值对象的集合,如何构造该对象?
举个例子,假设您有一个picture需要多个dimensions
选项1 :
Class Picture implements valueObject{
public function __construct(array $dimensions){
foreach($dimensions as $dimension){
// check if instance of `dimension` value object
}
}
}
Run Code Online (Sandbox Code Playgroud)
选项2:
Class Picture implements valueObject{
public function __construct(DimensionCollection $dimensions){
}
}
Class DimensionCollection implements Traversable{
public function add(Dimension $dimension){
// add to array
}
}
Run Code Online (Sandbox Code Playgroud)
选项2偏离路线似乎更合乎逻辑,但是是否有另一种模式可以更好地从DDD的接受角度出发?
我是DDD的新手,我正在开发一个实现DDD概念的项目.
我知道在DDD中我们有Entities和Value对象,我知道在值对象的情况下,如果我们需要确保它们的相等性,我们应该比较每个值对象的属性值.
我们使用C#作为编程语言,我想知道为什么我们需要重写GetHashCode()和Equals()方法?
我的意思是为什么我们不比较属性的值来比较值对象?
问题
数据传输对象(DTO)可以引用域模型的值对象(VO)吗?
语境
在我的域中,我有一个导入器,它从集合中导入聚合。该集合由进口商依赖的收集器构建的 DTO 组成。由于导入器和收集器都是我的域的服务(接口),DTO 是否可以引用域值对象,或者我应该坚持使用原语并仅在处理集合(聚合的构建)时将它们转换为值对象?
收集器实现,其中构建了由域模型中的值对象组成的 DTO
<?php
/**
* i-MSCP Patcher plugin
*
* @author Laurent Declercq <l.declercq@nuxwin.com>
* @copyright (C) 2019 Laurent Declercq <l.declercq@nuxwin.com>
* @license i-MSCP License <https://www.i-mscp.net/license-agreement.html>
*/
/**
* @noinspection
* PhpUnhandledExceptionInspection
* PhpDocMissingThrowsInspection
*/
declare(strict_types=1);
namespace iMSCP\Plugin\Patcher\Infrastructure\Domain\Service\Component\Importer;
use iMSCP\Plugin\Patcher\Domain\Model\Component\ComponentBuild;
use iMSCP\Plugin\Patcher\Domain\Model\Component\ComponentName;
use iMSCP\Plugin\Patcher\Domain\Model\Component\ComponentVersion;
use iMSCP\Plugin\Patcher\Domain\Service\Component\Importer\ComponentCollector;
use iMSCP\Plugin\Patcher\Domain\Service\Component\Importer\DTO\ComponentDTO;
use iMSCP\Plugin\Patcher\Domain\Service\Component\Importer\DTO\ComponentDTOCollection;
use iMSCP_Config_Handler_File as MergedConfig;
use iMSCP_Plugin_Manager as PluginManager;
use RuntimeException;
use Throwable;
/**
* Class DefaultComponentCollector
* @package iMSCP\Plugin\Patcher\Infrastructure\Domain\Service\Component\Importer
*/
class DefaultComponentCollector implements …Run Code Online (Sandbox Code Playgroud) 我试图理解POCO的确切含义(是的,我已经读过维基百科,但仍然无法得到主要观点:().
我知道Value Object是一个对象,基本上只有属性来保持数据没有任何行为.
在这种情况下,在我看来,POCO和'Value Objects'具有相同的结构,但不同之处在于POCO的目标是.net框架.
我对么?
谢谢.
value-objects ×10
c# ×2
entity ×2
.net ×1
architecture ×1
collections ×1
cqrs ×1
database ×1
dto ×1
equality ×1
nhibernate ×1
oop ×1
php ×1
poco ×1
traversal ×1