Oop 抽象是。。。太抽象了?

Oop 抽象是。。。太抽象了?,oop,inheritance,domain-driven-design,Oop,Inheritance,Domain Driven Design,在沃恩·弗农(Vaughn Vernon)的领域驱动设计(Domain Driven Design)一书中,我们应该尽量避免创建可能过于抽象的技术抽象,并通过坚持普遍存在的语言的概念来尝试更加明确 在我工作的地方,我们已经构建了几个跟踪应用程序,几乎在每个应用程序中都存在同一事物的多个专门化的问题,最有可能是常见的行为,但不同的数据和验证规则 例如,想象一个事件日志应用程序,其中通过电话报告各种类型的事件(例如车祸、火灾、抢劫)。信息收集过程类似于每个事件,但捕获的数据可能会有很大差异,以及限制

在沃恩·弗农(Vaughn Vernon)的领域驱动设计(Domain Driven Design)一书中,我们应该尽量避免创建可能过于抽象的技术抽象,并通过坚持普遍存在的语言的概念来尝试更加明确

在我工作的地方,我们已经构建了几个跟踪应用程序,几乎在每个应用程序中都存在同一事物的多个专门化的问题,最有可能是常见的行为,但不同的数据和验证规则

例如,想象一个事件日志应用程序,其中通过电话报告各种类型的事件(例如车祸、火灾、抢劫)。信息收集过程类似于每个事件,但捕获的数据可能会有很大差异,以及限制这些数据的验证规则

到目前为止,我们总是用非常技术性的抽象来解决这类问题(这是一个过于简单的模型,但你应该明白这一点):

如您所见,
DataValidationRules
数据字段
DataEntries
抽象与事件日志记录业务关系不大。实际上,它们是一个非常通用的解决方案的一部分,用于解决在任何域中用不同数据表示多个实体专门化的问题

我想摆脱这种非常抽象的模型,但同时我不认为什么是使业务概念明确化的正确方法。我知道每个领域的答案都是不同的,但本质上,我应该考虑每个专业都有一个类吗?例如,
caracidentindication
火灾事件
抢劫事件

由于专业化的数量非常有限,这似乎是可以管理的,但如果我有数百个呢

用户界面呢?这意味着我也必须放弃生成UI的通用方法


在仔细考虑之后,我想我可能已经找到了一种更好、更简单的方式来表达我对DDD、OO和许多专门化建模的关注

一方面,我想提出一个模型,它忠实于泛在语言(UL)和模型域概念。另一方面,我正试图尊重我已经习以为常的“重组合轻继承”的咒语

这两者似乎是相互冲突的,因为为了实现组合,我必须引入最有可能不是UL的一部分的抽象(例如,
实体——字段
组合),当涉及到显式建模时,我看不到任何其他方式,除了每个专门化一个类的继承

我试图避免继承来表示数百个主要在数据结构而不是行为方面不同的专门实体,这是错误的吗

再说一次,假设他们在行为上也有很大不同,我也会面临同样的困境


只是为了更明确地说明设计选择:

在一种情况下,合成是可以动态实现的,而不需要每个专用合成有多个类:

class Incident {
    Set<Detail> details;
    IncidentType type;
}

interface Detail {
    public DetailType type();
}

class SomeDetail implements Detail {
    ...
}

class SomeOtherDetail implements Detail {
    ...
}
显然,第二种方法更加明确,为特定的行为和规则提供了一个自然的家。在第一种方法中,我们必须引入一些抽象和技术概念,如
操作
详细验证
,这些概念可能与UL不一致

由于有少量不同的专业,我可能会毫不犹豫地选择后者,但因为有很多专业,我似乎更倾向于动态构图(即使是动态构图也不是必需的)。我应该吗?

何时使用DDD? 问题是,DDD不一定适合所有系统。它特别适合于具有复杂业务规则的大型系统


如果需要表达以捕获FireIncident本质的业务规则足够简单,可以编码在
DataValidationRules
记录和一组
数据字段中,那么这表明这些规则可能不需要DDD实现的复杂性

数据验证领域 然而,如果您承认这一点,您可以将您的视角转向实际构建纯数据验证引擎。数据验证领域应包括数据验证规则和数据字段等实体,并考虑与规则和字段的生命周期相关的问题,例如“如果验证规则发生变化,会发生什么情况?是否所有先前已验证的现有记录都需要重新验证?”

如果数据验证规则本身的生命周期复杂到足以保证它的存在,那么无论如何,请使用DDD来实现该域,尽管如果发现数据验证域中没有复杂的规则或过程,您仍然可以选择使用CRUD

谁是你的领域专家? 进一步的结果是,您的领域专家不再是您的最终用户(了解车祸和火灾事件的人),他们现在是制定验证规则和字段的人(最有可能是专家)。如果使用DDD,您需要询问他们需要什么类型的规则以及他们需要这些规则如何工作,并使用他们用来谈论制定验证规则的艺术和过程的普遍语言来实现

反过来,这些人将使用您的数据验证引擎“编程”下一个级别的系统(您可能会说他们使用的是针对事件记录领域定制的系统)。问题是,他们的领域专家将是那些知道车祸的人。但是专家们不会严格使用DDD来制定车祸规则,因为他们不会用软件来表达他们的模型,而是用数据采集和分析的受限语言
class CarAccidentIncident extends Incident {
    SomeDetail someDetail;
    SomeOtherDetail someOtherDetail;
}


class SomeDetail {}
class SomeOtherDetail {}