1

我有一个 Java 应用程序,其中域层通过控制器与 UI 分离。问题是这些控制器可以返回域对象,并且可以将域对象作为参数。

其中一些返回的域对象是可变的,这就是我想要阻止的。我希望 UI(或未来的 UI)在不访问控制器的情况下直接修改域是不可能的。

我尝试了两种选择:

  • 在第一个中,我确保每个类都实现了一个只包含 getter的“不可修改”接口。如果我需要将一个对象返回给 UI,我会返回它的“不可修改”界面。这样 UI 只能查看 getter。这样做的问题是它们仍然可以轻松地转换为原始对象并获得访问权限。起初我以为这种级别的安全性已经足够了,但碰巧有人不小心铸造了一些物体并以不正确的方式使用它们,从而破坏了完整性。

  • 在第二个中,我尝试为每个可以返回的对象提供不可修改的包装器。但问题是这些返回的对象可以用作控制器中方法的参数,因此它们需要在控制器中展开。我试图使uwrap()方法包私有,但是我必须将每个特定的包装类与控制器放在同一个包中,这有点不方便。

编辑:第三个选项:

  • (感谢vic)在第三个选项中,对象被一个不可修改的wrapper 包裹,但不能被这个 wrapper 解包。每个 Unmodifiable 都链接到其在 Hashmap 中的可修改对象。因此,“展开”是通过获取链接到不可修改对象的可修改对象来完成的。

有没有人知道或有一些想法如何使对象不可修改,以便控制器可以返回它们,并在将它们传递回控制器时使它们再次可修改成为可能?

4

2 回答 2

2

如果控制器私下存储对象的可变版本并将其不可变版本返回给“外部世界”会怎样。可变版本将具有某种唯一的 id,控制器将能够通过某种方式unwrap查找它。Collection

于 2012-02-18T14:27:52.783 回答
2

选择状态设计模式,这是表示对象状态的绝佳选择。

基本上,每当 UI 想要显示域对象时,控制器都会给它一个不可变的 DTO 对象,表示对象本身的快照。这将限制 UI 层仅具有域对象的不可变快照。当 UI 想要更改您的域对象时,它会将不可变状态对象发送到控制器,控制器使用它们在内部修改相应的域对象。

于 2012-02-18T14:39:09.803 回答