[英]Determining Entities and Value Objects in Domain Driven Design in a real project
This is for the first time I am implementing the concept of Domain Driven Design in a real project. 这是我第一次在实际项目中实现域驱动设计的概念。 The project is about generating a permit for employees which would enable them to enter company premises. 该项目是关于为员工签发许可证,使他们能够进入公司场所。 Through an Intranet site, an employee who already possesses an Employee ID, will be able to apply for a permit or apply for replacement of a permit, in case the permit is damaged or lost. 通过Intranet网站,已经拥有员工ID的员工将能够申请许可证或在许可证被损坏或丢失的情况下申请更换许可证。 And an administrator will process the applications and hand over a physical permit in the end. 管理员将处理申请并最终交出实际许可。
I have a couple of entities - User
, Permit
and one Value Object - Employee
. 我有几个实体- User
, Permit
和一个价值对象- Employee
。
User
can be entirely identified by an Employee
. User
可以完全由Employee
标识。 Should I create a UserId
as well? 我也应该创建一个UserId
吗? How do I handle the case in which the administrator may not only approve, but raise an application on behalf of an employee as well? 我该如何处理管理员不仅可以批准,还可以代表员工提出申请的情况? Employee
has an Id property EmployeeId
which I know goes against the principle of a Value Object. 值对象Employee
有一个Id属性EmployeeId
,我知道这违反了值对象的原理。 However, in my case, Employee
is read-only. 但是,就我而言, Employee
是只读的。 It doesn't matter to me if I get only the EmployeeId
or the Employee
as a whole. 对于我来说,仅获得EmployeeId
还是整个Employee
都无关紧要。 Am I doing this right? 我这样做对吗? Permit
entity contains a lot of properties. Permit
实体包含许多属性。 How do I break down the properties of Permit
into Value Objects? 如何将“ Permit
的属性分解为“价值对象”? public class User : Entity
{
public Employee Employee { get; set; }
public bool IsAdmin { get; set; }
}
public class Permit: Entity
{
public int ApplicationId { get; set; }
public string EmployeeId { get; set; }
public string Type { get; set; }
public string Status { get; set; }
public DateTime RequestDate { get; set; }
public DateTime IssuanceDate { get; set; }
public string IssuanceReason { get; set; }
public string SurrenderReason { get; set; }
}
public sealed class Employee : ValueObject<Employee>
{
public string EmployeeId { get; private set; }
public string Name { get; private set; }
public string Department { get; private set; }
public string Division { get; private set; }
public string BirthDate { get; private set; }
public string Designation { get; private set; }
public string BloodGroup { get; private set; }
public string SecurityLevel { get; private set; }
public string EmploymentDate { get; private set; }
}
Apart from the concerns, I'd be grateful if someone could guide me to go about it in the most appropriate manner possible. 除了担心之外,如果有人可以引导我以最合适的方式进行处理,我将不胜感激。 Thanks. 谢谢。
You should create 3 entities 您应该创建3个实体
Give it all an UniqueId --> because they are entity's so they are unique When there is a relation , for example between User and Employee, You can use a value object Employee (so 2 VO's) 全部赋予一个UniqueId->,因为它们是实体的,所以它们是唯一的当在用户和Employee之间存在关系时,例如,您可以使用值对象Employee(所以2个VO)
From my point of perspective it would be better to discard the User
class, as it closely resembles the Employee
class. 从我的角度来看,最好丢弃User
类,因为它与Employee
类非常相似。
The property IsAdmin
is a very hard constraint, from a broader perspective you could create an Enum
that represents security groups. IsAdmin
属性是一个非常严格的约束,从更广泛的角度来看,您可以创建一个代表安全组的Enum
。 This enables you to implement security for certain areas where given group X has access and group Y does not. 这使您可以为给定组X可以访问而组Y没有访问的某些区域实施安全性。 This could replace the string SecurityLevel
in the Employee
class. 这可以替换Employee
类中的string SecurityLevel
。 You could also implement these security groups in the Permit
class. 您也可以在Permit
类中实现这些安全组。
The Permit
class should be used by the Employee
class. Permit
类应由Employee
类使用。 A user can have multiple permits, active and non-active. 一个用户可以有多个许可,包括活动许可和非活动许可。 A boolean value defining that logic should be implemented into the Permit
class. 定义应该在Permit
类中实现的逻辑的布尔值。 By implementing the active/non-active boolean in the Permit
class, you could revoke access by simply switching the value of the boolean. 通过在Permit
类中实现活动/非活动布尔值,您可以通过简单地切换布尔值来撤消访问。
In modeling business processes, it will often help to think about the paperwork , rather than the things in the real world. 在对业务流程进行建模时,通常会考虑到文书工作 ,而不是现实世界中的事情。 The process begins when somebody files a request document, it ends when the adminstrator files an approval or a rejection, and so on. 当有人提交请求文档时,该过程开始;当管理员提交批准或拒绝等时,该过程结束。 The domain model's job is to do the bookkeeping, and to perform some of the logic on behalf of the business. 领域模型的工作是进行簿记,并代表业务执行一些逻辑。
See 看到
Should I create a UserId as well? 我也应该创建一个UserId吗?
If you need to handle the case where the person submitting the request is different from the person the permit is assigned to, then you should absolutely treat those as different values. 如果您需要处理提交请求的人与被分配许可的人不同的情况,那么您绝对应该将这些人视为不同的值。
It doesn't matter to me if I get only the EmployeeId or the Employee as a whole. 对于我来说,仅获得EmployeeId还是整个Employee都无关紧要。 Am I doing this right? 我这样做对吗?
Yes - there is nothing wrong with an immutable value having an identifier. 是的-具有标识符的不可变值没有错。
In more sophisticated models, value objects will often be composed from other value objects. 在更复杂的模型中,价值对象通常将由其他价值对象组成。 For example, event though EmployeeId
and BloodGroup
are opaque character sequences, it's probably not OK to pass a blood group to a method that is expecting an employee id, or vice versa. 例如,尽管EmployeeId
和BloodGroup
是不透明的字符序列,但如果将血型传递给需要雇员ID的方法,则可能BloodGroup
,反之亦然。 So rather than leaving things "stringly typed", we might invest more work in the model to make those concepts explicit. 因此,我们可能不做任何“字符串类型化”的事情,而是可能在模型中投入更多的工作来使这些概念明确。
How do I break down the properties of Permit into Value Objects? 如何将“许可证”的属性分解为“价值对象”?
Again, values can be composed from other values. 同样,值可以由其他值组成。 If there is a subset of cohesive properties, group them together. 如果存在内聚性的子集,请将它们组合在一起。
Scott Wlaschin's Domain Modeling Made Functional is a great reference here. Scott Wlaschin的功能性领域建模是一个很好的参考。
Part of the point of "objects" is that we should be able to change the in memory data structures and still have everything "work". “物”的点的部分原因是,我们应该能够改变内存中的数据结构,仍然拥有一切“工作”。 So you shouldn't feel like you are committed to a particular in memory layout. 因此,您不应感到自己致力于内存布局中的特定事项。
(Note: it's really easily to couple your in memory layout to your persistent storage -- that will make things harder to change later; so try not to fall into that trap more than once.) (注意:将您的内存布局与持久性存储耦合起来真的很容易-这会使事情在以后很难更改;因此,请避免多次陷入该陷阱。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.