Java 实体惰性方法与Dimetra定律
我有一个实体:Java 实体惰性方法与Dimetra定律,java,design-patterns,entity,design-principles,Java,Design Patterns,Entity,Design Principles,我有一个实体: @Entity @Table(name = "CARDS") public class Card { @ManyToOne @JoinColumn(name = "PERSON_ID", referencedColumnName = "ID", nullable = false) private Person person; @OneToMany(mappedBy = "card") private List<CardStatus> cardS
@Entity
@Table(name = "CARDS")
public class Card {
@ManyToOne
@JoinColumn(name = "PERSON_ID", referencedColumnName = "ID", nullable = false)
private Person person;
@OneToMany(mappedBy = "card")
private List<CardStatus> cardStatuses;
card.getCardStatuses().get(0).getSomething()-getCardStatuses
是LAZY
我的问题-这个挑战是否违反了Dimetra法律
得墨忒尔定律有一个著名的启发法,叫做德米特定律
Demeter2说模块不应该知道
它操纵的对象。正如我们在上一节中看到的,对象是隐藏的
他们的数据和公开操作。这意味着一个对象不应该
通过访问器公开其内部结构,因为这样做是为了
暴露而不是隐藏其内部结构。更准确地说,,
德米特定律说C类的方法f只应该调用
这些方法包括:
• C
• An object created by f
• An object passed as an argument to f
• An object held in an instance variable of C
该方法不应调用由返回的对象上的方法
任何允许的函数。换句话说,与朋友交谈,而不是与朋友交谈
陌生人。以下代码似乎违反了德米特法
(除其他外)因为它在
getOptions()的返回值,然后在上调用getAbsolutePath()
getScratchDir()的返回值。最终字符串outputDir=
ctxt.getOptions().getScratchDir().getAbsolutePath()
卡
-是数据结构,不违反Dimetra法律,但惰性
方法具有logik(使选择数据库)
这项挑战是否违反Dimetra法律?如果是,我如何正确使用它
我有很多代码,比如:
entityOblect.getChield().getChield().getSomething();
编辑
从Cleand代码手册:
EDIT2
(c) 罗伯特·c·马丁-清洁代码
活动记录活动记录是DTO的特殊形式。它们是数据
具有公共(或被访问)变量的结构;但他们通常
使用诸如保存和查找之类的导航方法。通常,这些是活动的
记录是数据库表或其他数据的直接转换
来源。不幸的是,我们经常发现开发人员试图
这些数据结构就像是通过将业务
规则中的方法。这是尴尬的,因为它创建了一个混合
在数据结构和对象之间。当然,解决办法是
将活动记录视为数据结构,并创建单独的
包含业务规则并隐藏其内部规则的对象
数据(可能只是活动记录的实例)
这违反了德米特法:
Something something = card.getCardStatuses().get(0).getSomething();
在一条语句中,您可以浏览所有这些对象:卡片
->列表
->卡片状态
->某物
理想情况下,您应该从客户端进行此通信:卡片
->某物
在Card
类中,Something
返回可以通过执行以下导航的方法实现:列表
->卡片状态
->某物
在某种程度上,最后一个也违反DEMETER定律,但在一个我们认为可以接受的级别上,因为我们不应该把这个关系看作代码> >清单>代码> ->代码> CARDSTATION/CODE >作为陌生人关系。p> 它可以提供:
Something something = card.getSomethingOfCardStatuses(0);
或避免使用get前缀:
而findsomethingofcardstatus()
可以在卡中定义为:
public Something findSomethingOfCardStatuses(int statusNumber){
// add some check for the index if required
// you could return Optional or an Exception according to your requirements
return cardStatuses.get(0).getSomething();
}
我知道许多开发人员喜欢在实体字段中手动挖掘,但就我个人而言,我避免这样做,我尝试给他们一些有意义的名称和行为的逻辑方法。它使核心更加清晰 那你说的是我首先想到的。我完全同意。但是卡片是一个实体。在实体类中创建其他方法-是否正确?我认为实体应该是表的反映,而不是更多。否?通常有两种方法:哑数据模型或智能数据模型。我总是喜欢第二个。实体既可以是关系表在OOP中的表示,也可以是定义某些逻辑的类。为什么你想让这两个方面在他们之间互斥?我是eddit的问题。从书中添加片段我认为实体是数据结构,它不能有额外的方法和行为。若我向实体添加一些方法,它将混合(数据结构和行为对象)。我认为实体必须是简单的。在这个例子中,作者给出了一个糟糕的用例,他指的是域对象中的方法的乘法。这不是你的情况。我认为“混合结构”部分确实不清楚其边界和风险。例如:在数据结构中添加一些helper方法并不意味着在中添加核心逻辑,也不应该在设计中产生任何问题。当然,我更喜欢Martin Fowler关于领域模型设计的解释。在这里,您将建立贫血领域模型:
Something something = card.findSomethingOfCardStatuses(0);
public Something findSomethingOfCardStatuses(int statusNumber){
// add some check for the index if required
// you could return Optional or an Exception according to your requirements
return cardStatuses.get(0).getSomething();
}