到目前为止,我已经理解了实体对象具有ID,而值对象没有,但在最常见的示例中,您具有附加了地址值对象的person实体.创建单独的地址对象而不仅仅是在Person Entity中保留地址属性有什么大的优势?
我有一个包含Address作为值对象的person实体:
public Person()
{
WithTable("Person");
Id(x => x.Id);
Component<Address>(x => x.Address, a =>
{
a.Map(x => x.Address1);
a.Map(x => x.Address2);
a.Map(x => x.Address3);
a.Map(x => x.Town);
a.Map(x => x.Postcode);
});
}
Run Code Online (Sandbox Code Playgroud)
它在NHibernate文档中指出,如果值对象(Address1,Address2等)的所有属性都为null,则整个组件将被映射为null(即Person.Address将为null).这给了我所有地址字段为空的情况下的问题,因为在我的网页中我可能有(我正在做ASP MVC):
<%= Html.TextBoxFor((x => x.Address.Address1))%>
Run Code Online (Sandbox Code Playgroud)
这打破了空引用异常.所以我正在寻找一种简洁的方法将Address设置为一个新的Address()对象而不是null,如果我从数据库加载Person而不手动操作时所有字段都是空的.我打了以下想法:
在我的视图中进行空检查(yuk,可怕)
使数据库字段不可为空(我正在处理遗留数据库)
任何想法?
数据传输对象与值对象相同还是不同?如果它们不同,那么我们应该在哪里使用DTO?我们应该在哪里使用VO?
我们谈论的编程语言是Java,上下文是 - 有一个Web应用程序,它从数据库中获取数据然后处理它,最终处理后的信息显示在前端
java design-patterns web-applications data-transfer-objects value-objects
在哪种情况下我可以在n层架构中使用这些设计模式?
这是一个很长的问题,所以我要直截了当.这是伪代码,可以更好地说明问题
数据库结构
用户(UserID,Name,LastName)
地址(AddressID,UserID,Street,City,State,ZipCode)=>多对一用户关系
电话(PhoneID,UserID,Number,IsPrimary)=>多对一用户关系
域类
class User:IEntity
{
public string Name {get;set;}
public string LastName {get;set;}
public ContactInfo{get;set;}
}
class Phone: IValueObject or IEntity? will see later.
{
public int id; // persistence ID, not domain ID
public string Number {get;set;}
}
class Address: IValueObject or IEntity? will see later.
{
public string Line1 {get;set;}
public string City {get;set;}
public string State {get;set;}
public string ZipCode {get;set;}
}
class ContactInfo: IValueObject or IEntity? will see later.
{
List<Address> Addresses …Run Code Online (Sandbox Code Playgroud) 在领域驱动设计中,我们引入了 a 的概念ValueObject,其中对象不带有标识。
Microsoft在其微服务系列中提供了它们的实现ValueObject,其中它们进行了覆盖Equals(),以便两个ValueObject具有相同值的 ' 被认为是相同的。
EqualOperator()我在下面列出了它们的实现,但我的问题与和方法有关NotEqualOperator()- 这是如何工作的?他们什么时候被叫?
我熟悉运算符重载,但这似乎是我以前从未见过的实现,而且我找不到任何有关它的文档。
这是实现:
public abstract class ValueObject
{
protected static bool EqualOperator(ValueObject left, ValueObject right)
{
if (ReferenceEquals(left, null) ^ ReferenceEquals(right, null))
{
return false;
}
return ReferenceEquals(left, null) || left.Equals(right);
}
protected static bool NotEqualOperator(ValueObject left,
ValueObject right)
{
return !(EqualOperator(left, right));
}
protected abstract IEnumerable<object> GetAtomicValues();
public override bool Equals(object obj)
{
if (obj == null || …Run Code Online (Sandbox Code Playgroud) 我正试图结合一些技巧.
从来没有可能创建一个无效的ValueObject似乎是一种好习惯.只要提供的内容不足以创建有效的ValueObject,ValueObject构造函数就会失败.在我的示例中,只有存在值时才能创建EmailAddress对象.到现在为止还挺好.
验证提供的电子邮件地址的价值,这就是我开始怀疑原则的地方.我有四个例子,但我不知道哪一个应该被认为是最好的做法.
示例1很简单:只需构造函数,必需参数"value"和单独的函数验证以保持代码清洁.所有验证代码都保留在类中,并且永远不会对外界可用.该类只有一个目的:存储emailaddress,并确保它永远不会是无效的.但代码永远不会重复使用 - 我用它创建了一个对象,但就是这样.
public function __construct ($value)
{
if ( $this->validate($value) )
{
throw new \ValidationException('This is not an emailaddress.');
}
$this->value = $value;
}
protected function validate ($value)
{
return is_string($value); // Wrong function, just an example
}
Run Code Online (Sandbox Code Playgroud)
示例2使validate函数成为静态函数.该函数永远不会改变类的状态,因此它正确使用了static关键字,并且其中的代码永远不能将任何内容更改为嵌入静态函数的类创建的任何实例.但是如果我想重用代码,我可以调用静态函数.不过,这让我觉得很脏.
public function __construct ($value)
{
if ( $self::validate($value) )
{
throw new \ValidationException('This is not an emailaddress.');
}
$this->value = $value;
}
public static function validate ($value)
{
return is_string($value); // Wrong function, just an example
} …Run Code Online (Sandbox Code Playgroud) php validation domain-driven-design dependency-injection value-objects
我最近一直在研究领域驱动设计,并且必须说这种类型的架构设计触发了我的某些东西。当我尝试将其概念应用于我的 Go 项目时,我遇到了一些障碍。以下是一些示例方法,但我非常不确定要使用哪种方法。
项目结构摘录:
??? api/
??? cmd/
??? internal/
| ??? base/
| | ??? eid.go
| | ??? entity.go
| | ??? value_object.go
| ??? modules/
| | ??? realm/
| | | ??? api/
| | | ??? domain/
| | | | ??? realm/
| | | | | ??? service/
| | | | | ??? friendly_name.go
| | | | | ??? realm.go
| | | | | ??? realm_test.go
| | | | …Run Code Online (Sandbox Code Playgroud) 我已经阅读了很多关于Value Objects的C#示例,我知道它是一个由它的值标识的"对象".如果值更改,则对象为"new".
但是,当涉及到PHP时,这似乎没有意义......或者我只是没有建立连接.
值对象只是一个字符串吗?
我正在努力使用 Entity Framework Core 创建一个不可为空/必需的拥有类型。我正在对 PostgreSQL 数据库使用 EF Core 3.0。
我的价值对象:
public class PersonName
{
public PersonName(string name)
{
this.Name = name;
}
public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我的实体:
public class Person
{
public int Id { get; set; }
public virtual PersonName FullName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我的实体配置:
public void Configure(EntityTypeBuilder<Person> builder)
{
builder.ToTable(nameof(Person));
builder.HasKey(person => person.Id);
builder.OwnsOne(person => person.FullName, personName =>
{
personName.Property(pn => pn.Name).IsRequired().HasColumnName("FullName");
});
}
Run Code Online (Sandbox Code Playgroud)
值类型属性已成功保存到数据库中的“Person”表中,但尽管我使用的是“IsRequired()”方法,但该列仍然可以为空。
非常感谢!
c# postgresql value-objects entity-framework-core owned-types
value-objects ×10
c# ×2
java ×2
php ×2
cqrs ×1
entities ×1
go ×1
null ×1
owned-types ×1
postgresql ×1
validation ×1