我有一个类,它应该充当实体类(如 DDD 中)。它基本上看起来像这样:
public class Page
{
protected String Name;
protected String Description;
protected Dictionary<int, IField> Fields = new Dictionary<int, IField>();
protected Page SetName(String name)
{
this.Name = name;
return this;
}
protected Page SetDescription(String description)
{
this.Description = description;
return this;
}
public Page AddField(IField field)
{
this.Fields.add(xxx, Field); //xxx = just some id
return this;
}
}
Run Code Online (Sandbox Code Playgroud)
现在我的问题是,这是一个有效的实体类吗?
我需要保持方法链接,所以请不要对此进行太多详细说明(即使您认为这是错误的)。
我主要关心的是,实体类是否可以包含方法,例如 getter 和 setter?尤其是像AddField?这样的方法
该AddField方法采用 类型的对象IField。我将其存储在班级内的字典中Page。那么这就是一个总和,对吗?
这不会改变实体的状态,使其不是真正的实体类吗?
还是就这样就可以了?
我有一个场景,需要验证域实体属性的唯一性,然后才能将其保存到数据库。这是一个简单的Product类。假设我想验证在创建新产品时ProductKey 字符串属性是唯一的:
public class Product : EntityBase
{
int ID { get; set; }
string ProductKey { get; set; }
int CategoryID { get; set; }
bool IsValid
{
get
{
if (string.IsNullOrEmpty(ProductKey))
{
ValidationErrors.Add("ProductKey Required.");
}
if (CategoryID == 0)
{
ValidationErrors.Add("CategoryID Required.");
}
/* Validation that the product key is unique could go here? i.e. requires a database read. */
return ValidationErrors.Count() == 0;
}
}
}
Run Code Online (Sandbox Code Playgroud)
由于我使用领域驱动设计,产品实体不了解持久性或服务层。我可以向 Service 方法添加一个检查,如下所示:
public class ProductService
{ …Run Code Online (Sandbox Code Playgroud) 我提前道歉,因为这个问题几乎有点愚蠢。尽管如此,我自己也想不出一个好的解决方案,所以我认为还是值得问一下。
当 Representation 对象和 Domain 对象应该具有相同的名称时该怎么办?DDD 示例并没有真正解决表示层问题,因此我无法在那里找到帮助。Account 类与任何其他类一样可以说明:
package com.mycompany.myproduct.representation;
public class Account {
private String uuid;
private String accountNumber;
// etc
@JsonCreator
public Account(@JsonProperty('uuid) String ....
}
Run Code Online (Sandbox Code Playgroud)
也许这个系统有一个约定,只要有可能,就以字符串形式返回数据。但我喜欢这里有所有 Json 注释。虽然这意味着 XML 并未得到真正的支持,但目前看来还可以,不过如果有更多的灵活性就更好了。那么在Domain层中可能还有另一个这样的类:
package com.mycompany.myproduct.domain.model;
import java.uti.UUID;
public class Account extends Entity {
private UUID id;
private BigDecimal accountNumber;
// ... business logic, etc
}
Run Code Online (Sandbox Code Playgroud)
如果这两种数据类型的名称相同,那么在它们最终必须满足的情况下,代码将变得丑陋/不支持。作为通用语言的一部分,域层似乎必须有帐户类。但外界谈论的是表征对象。如果那是他们的语言,为什么他们要使用不同的语言?
我正在为一项新服务创建高级设计。服务的复杂性需要使用 DDD(我认为)。所以我做了常规的事情并创建了域服务、聚合、存储库等。我的存储库封装了数据源。因此,查询可以在缓存中查找对象,如果在数据库中查找失败,则调用REST外部服务来获取所需信息。这是相当标准的。现在我的同事提出的论点是,以这种方式抽象数据源是危险的,因为使用存储库的开发人员将不知道执行 api 所需的时间,因此无法计算他所访问的任何 api 的执行时间。上面写着。如果他知道他的调用会导致调用,他可能会想要以不同的方式设置他的组件的行为REST。他们建议我将调用移到REST存储库之外,甚至可能将缓存策略也随之移出。我可以理解他们的观点,但存储库模式背后的整个想法正是隐藏此类信息,而不是让每个组件处理缓存策略和数据访问。我的问题是,是否有一种模式或模型可以解决这个问题?
rest domain-driven-design ddd-repositories repository-pattern ddd-service
我遇到了电子商务应用程序的微服务架构,其中每个表都有自己的微服务,基本上具有 CRUD 操作(类似于每个表的其余客户端)。现在我正在考虑围绕业务领域对它们进行组合和建模,在此之前我想知道是否有人遇到过这种情况以及它是否正确的架构。任何建议都会非常有帮助。谢谢。
我们在当前的项目中使用 DDD 实践。我们的问题是我们有很多有界上下文,每个上下文都是一个包含其持久层的分层架构。问题是,例如在有界上下文中,我们需要引用其他有界上下文中的数据,例如IdentityAccess上下文是负责管理用户的上下文,因此它包含UserModel但我们需要在另一个有界上下文中引用用户因此,我们创建一个SubscriberUserModel,其中包含该有界上下文中用户模型的子集信息。我们有一个迁移项目,其中包含来自所有有界上下文的所有模型,用于管理迁移和数据库,但我们面临一个问题。我们不能有多个实体引用同一个表我的问题是如何以一种聪明的方式处理这个问题这是当我们尝试生成新迁移时的 EF 异常
我试图理解 java POJO 的最佳设计概念。如果我有一个car像这样的对象:
public class Car {
private String color;
private String make;
private String model;
private int year;
public Car(String color, String make, String model, int year) {
this.color = color;
this.make = make;
this.model = model;
this.year = year;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getMake() {
return make;
}
public void setMake(String make) {
this.make = make;
}
public String getModel() …Run Code Online (Sandbox Code Playgroud) 为了说明这个问题,我们使用一个简单的例子:有两个聚合 -Lamp和Socket。必须始终强制执行以下业务规则: aLamp和 aSocket都不能同时连接多次。为了提供适当的命令,我们设想了一个Connector带有Connect(Lamp, Socket)-method 的服务来插入它们。
因为我们希望遵守一个事务只涉及一个聚合的规则,所以不建议在事务中对两个聚合设置关联Connect。所以我们需要一个象征Connection自身的中间蕴。因此Connect-transaction 只会Connection使用给定的组件创建一个新的。不幸的是,此时麻烦开始了;如何保证连接状态的一致性?可能会发生许多并发用户想要在同一时间插入相同的组件,因此我们的“一致性检查”不会拒绝该请求。新的Connection聚合将被存储,因为我们只锁定聚合级别。即使不知道这一点,系统也会不一致。
但是我们应该如何设定聚合的边界来确保我们的业务规则呢?我们可以设想一个Connections聚合,它收集所有活动连接(作为Connection实体),从而使我们的锁定算法能够正确拒绝重复的Connect请求。另一方面,这种方法效率低下且无法扩展,而且在领域语言方面也是违反直觉的。
你知道我错过了什么吗?
编辑:为了总结这个问题,想象一个聚合User。由于聚合的定义是基于事务的单元,我们可以通过锁定每个事务的该单元来强制不变量。一切皆好。但现在出现了一条业务规则:用户名必须是唯一的。因此,我们必须以某种方式使我们的总体边界与这一新要求相协调。假设有数百万用户同时注册,这就成了一个问题。我们尝试确保非锁定状态下的这种不变性,因为多个用户意味着多个聚合。
根据 Eric Evans 所著的《领域驱动设计》一书,一旦单个事务中涉及多个聚合,就应该应用最终一致性。但这真的是这样吗?这有道理吗?
在这里应用最终一致性需要注册User并随后使用用户名检查不变量。如果两个Users 实际上设置了相同的用户名,系统将撤消第二次注册并通知User. 想到这种情况让我感到不安,因为它扰乱了整个注册过程。例如,发送确认电子邮件必须延迟等等。
我想我只是忘记了一些一般的事情,但我不知道是什么。在我看来,我需要类似Repository级别上的不变量之类的东西。
据我所知,Clean Architecture/DDD 声明您的用例可以由任何东西触发,让它是 HTTP 请求或 GUI,对吗?
我正在尝试模仿这一点,但我不确定我是否做得正确。
在我的infrastructure文件夹中,我有路由器。例如:
import express from 'express'
import UserController from '../controllers/user_controller.js'
import ExpressRouterAdapter from './ExpressRouterAdapter.js'
export default function UsersRouter () {
const router = express.Router()
router.route('/:username').get(ExpressRouterAdapter.adapt(UserController.getUser))
return router
}
Run Code Online (Sandbox Code Playgroud)
(ExpressRouterAdapter只是将 Express 请求转换为简单的 httpRequest JS 对象的适配器)
这是我的GetUser控制器:
import express from 'express'
import UserController from '../controllers/user_controller.js'
import ExpressRouterAdapter from './ExpressRouterAdapter.js'
export default function UsersRouter () {
const router = express.Router()
router.route('/:username').get(ExpressRouterAdapter.adapt(UserController.getUser))
return router
}
Run Code Online (Sandbox Code Playgroud)
我有几个问题:
PostUser …我阅读了一些关于 DDD 的出版物和主题。关于聚合和实体之间的联系,有很多声音。我明白聚合应该尽可能简单(每个聚合一个实体)。但是当聚合具有实体集合时呢?
比方说,我们有一个名为“Month”的聚合,它包含一组“Day”对象(它们是域实体,因为它们需要一个标识来区分——让聚合知道要修改哪个“Day”)。
所以我有两个问题:
谢谢大家的回答