Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 对实体属性更改强制执行服务层业务规则,或者对客户端而不是服务隐藏实体属性?_Java_Oop - Fatal编程技术网

Java 对实体属性更改强制执行服务层业务规则,或者对客户端而不是服务隐藏实体属性?

Java 对实体属性更改强制执行服务层业务规则,或者对客户端而不是服务隐藏实体属性?,java,oop,Java,Oop,假设我有一个类Customer,它有一个属性customerType 我有另一个类叫做SpecialContract,它有一个客户和一些其他属性 如果customer.customerType==SPECIAL,则有一个SpecialContract引用此特定客户 现在我意识到这有点不合理,但我不想保持客户与特殊合同之间的关系,原因有几个,其中一个是在与客户合作时,大多数时候我们不需要加载特殊合同以及与特殊合同相关的所有其他数据。但是,我总是想知道客户是否有特殊合同,这是通过其customerT

假设我有一个类Customer,它有一个属性customerType

我有另一个类叫做SpecialContract,它有一个客户和一些其他属性

如果customer.customerType==SPECIAL,则有一个SpecialContract引用此特定客户

现在我意识到这有点不合理,但我不想保持客户特殊合同之间的关系,原因有几个,其中一个是在与客户合作时,大多数时候我们不需要加载特殊合同以及与特殊合同相关的所有其他数据。但是,我总是想知道客户是否有特殊合同,这是通过其customerType属性实现的

好的,这是最难的部分。我不希望客户机能够设置customerType,因为这样做不会删除应用于客户的特殊合同,这是必需的。我宁愿强制客户机调用服务方法来删除SpecialContract,这也会将customerType设置为NOTSPECIAL all-in-one事务


如何对客户端隐藏customerType setter,但仍将其公开给负责设置正确值并删除SpecialContract的服务层类?我的服务类别与客户类别不在同一个包中。

为什么不在启动时扫描系统,查找所有在
特殊合同中有引用的
客户
,将所有这些
客户
的列表存储在某个私人位置,例如,某个地方的服务层?

也许面向方面的编程在这里有一些用处。您可以拦截对传递合同的客户的调用,让before方法通知在给定特定条件的情况下实例化一个特殊的合同子类,然后将其传递给该方法。您只需设计合同层次结构,使其严格遵守Liskov替换原则


AOP可能会把这变成一个不可能的烂摊子,但这是另一种思考方式。您可以添加任意数量的规则,并以声明方式关闭或打开它们。

您可以创建一个
客户实现的
接口
,并将该
接口的实例传递给客户机。此
接口
不会向客户端公开
contentType
修改器。您的服务将处理成熟的
客户
对象,并且可以使用
中定义的
setContentType
修饰符

我不会试图对您的客户隐藏setter。相反,如果客户机修改了客户的状态并试图将其持久化,则应执行检查,以查看SpecialContract/customerType是否发生了不适当的更改,如果发生了异常,则可能会引发异常。然后,您可以创建前面提到的方法,该方法能够适当地更新SpecialContract/customerType


总的来说,我认为在靠近持久层的地方执行此检查会安全得多,这样它就有责任确保数据在保存之前是正确的,而不是接收发送过来的任何数据并盲目地持久化它。

看起来您必须对这些依赖项进行跟踪……我不确定这是否解决了问题问题问题在于保持Customer.customerType和SpecialContract.Customer的一致性。如果customerType setter是私有的,那么当特殊合同被销毁时,我不能在我的服务层中更改它。如果它是公共的,那么客户端可以将Customer.customerType设置为NOTSPECIAL,并在不(立即)销毁相应的SpecialContract的情况下将其持久化。我想我必须放弃这种方法。很有趣,谢谢。我想我最终会把它变成一个不可能的烂摊子:)