域驱动设计中的一组动态属性



经过搜索,我找不到任何答案,在我看来,这是一个相当常见的设计问题。

给定域对象:

public class Item {
    private Long itemSN;
    private String name;
    methods, etc...
}

我们需要存储描述一个项的一组特定的String属性。它可以是重量、颜色、尺寸等。系统必须灵活,并且能够持久保持可更改的属性列表。它需要存储允许的属性名称,最好强制执行其中的一些。

我尝试了几种方法,但所有Item对象共享的公共约束的概念并不适合任何标准的域模型。

所以我开始把约束看作一种配置形式。每个项都有自己的属性(在简单的字符串映射中),另一方面,约束是所有项的通用配置。所以下一个迪莱马出现了。。。如何在不建立大的领域模型的情况下表达它?

引入额外的应用层对象来存储约束很容易,但"允许/必需的属性"是业务事务,我们需要允许域用户(某种管理者)更改它,所以从域层提取这种逻辑真的很可怕。

欢迎提出任何建议。

编辑1.经过大量的头脑风暴,我设法为给定的情况创建了有效的对象模型。乍一看,用公共约束封装属性是不可能的,但最新的域外实现给了我一个想法:

public class Item {
    private Long itemSN;
    private String name;
    private List<Property> properties;
}

问题的核心在这里得到了解决:

public class Property {
    private Long propertyId;
    private String propertyValue;
    private Constraint constraint;
}
public class Constraint {
    private String name;
    private Boolean required;
    private List<String> allowedValues;
}

因此,每个属性都有其值和约束对象,它们指定名称、允许的值和所需的状态。通过这种方式,约束对象可以由许多属性共享,并且这些属性中的任何属性都可以具有自己的值。它为DB映射增加了一些复杂性,并将影响性能,但它也将所有域逻辑保留在域对象中。

欢迎任何改进、建议和意见。

使用注释可以非常合理地解决这个问题。通过注释,程序员可以继续使用该语言来使用特性,只需使用约束来注释特性,同时仍然可以在没有注释的情况下将相同的约束应用于用户定义的字段。

JSR-349是用于应用此类约束的Java标准。Hibernate验证器是一个众所周知的实现。

最新更新