物体种类
为了便于讨论,我们将对象分为三种不同的类型:
这些是完成工作的对象。他们将钱从一个支票帐户转移到另一个,执行订单,以及我们期望商业软件采取的所有其他行动。
域逻辑对象通常不需要访问器(getter和setter)。相反,您可以通过以下方式创建对象:将其依赖项通过构造函数处理,然后通过方法操作对象(告诉您,不要问)。
数据传输对象是纯状态。它们不包含任何业务逻辑。他们将始终具有访问器。它们可能带有或不带有setter,具体取决于您是否以不变的方式编写它们。您将在构造函数中设置字段,并且它们的值在对象的生存期内不会改变,或者您的访问器将被读/写。实际上,这些对象通常是可变的,以便用户可以对其进行编辑。
视图模型对象包含可显示/可编辑的数据表示形式。它们可能包含业务逻辑,通常仅限于数据验证。视图模型对象的一个示例可能是InvoiceViewModel,其中包含一个Customer对象,一个Invoice Header对象和Invoice Line Items。视图模型对象始终包含访问器。
因此,在不包含字段访问器的意义上,唯一的“纯”对象将是“域逻辑”对象。序列化此类对象可保存其当前的“计算状态”,以便以后可以检索它以完成处理。视图模型和DTO可以自由序列化,但是实际上它们的数据通常保存到数据库中。
序列化,依赖关系和耦合
确实,序列化会创建依赖关系,从某种意义上说,您必须反序列化为兼容的对象,但这并不一定意味着您必须更改序列化配置。好的序列化机制是通用的。他们不在乎是否更改属性或成员的名称,只要它仍然可以将值映射到成员即可。实际上,这仅意味着您必须重新序列化对象实例,以使序列化表示(xml,json等)与您的新对象兼容。无需对串行器进行任何配置更改。
确实,对象不应该关心它们的序列化方式。您已经描述了可以将此类问题与域类分离的一种方法:反射。但是,序列化程序应该考虑如何对对象进行序列化和反序列化。毕竟是它的功能。使对象与序列化过程脱钩的方法是使序列化成为通用功能,能够在所有对象类型上工作。
人们感到困惑的一件事是,必须在两个方向上进行去耦。它不是; 它只需要朝一个方向工作。实际上,您永远无法完全解耦。总会有一些耦合。松散耦合的目的是使代码维护更加容易,而不是删除所有依赖项。