【问题标题】:Use Android Room without breaking encapsulation在不破坏封装的情况下使用 Android Room
【发布时间】:2021-02-25 14:19:49
【问题描述】:

我正在使用 Room 来存储我的实体对象的数据。 Room 要求所有字段都可以公开访问(使用 getter/setter)。我还在 MVVM 模式中将此对象用作我的模型。由于该对象用于数据存储/持久性以外的目的,因此我想封装我的实体对象的字段(私有字段)。但是,我必须为我的方法公开公共 getter/setter(或将其声明为公共),这会破坏我的项目中的封装

我找到的唯一解决方案是专门为 Room 创建一个单独的对象作为实体对象,然后在数据持久化期间将我的模型转换为该对象。有没有更好的解决方案?我可以让我的字段的公共访问器只能由 Room 而不是其他类访问吗?

Java 或 Kotlin 的答案都可以。

如果您需要更多信息(例如 Entity 类的代码),请随时发表评论。

谢谢。

【问题讨论】:

  • 你走对了。使用 DB 时创建一个单独的对象。创建应用程序的更好方法是消除应用程序层之间的依赖关系(数据存储 - 业务逻辑 - ui)
  • 是的,我说的解决方案是可行的。但是,使用此解决方案,我必须在每次添加项目时将模型转换为对象(例如,当用户按下“添加项目”按钮时),然后再转换回来以获取模型。这很麻烦,我需要编写相当多的样板代码来管理这两种类型之间的转换。对于我添加到模型中的每个字段,我还必须确保它反映在单独的对象中,这可能会导致错误。
  • 如果我可以将对象直接存储在房间中而不需要单独的对象,我会更喜欢。

标签: android entity android-room encapsulation


【解决方案1】:

由于没有人发布答案,我将分享我所做的。

我专门为 Room 创建了一个单独的对象作为实体对象,然后在数据持久化期间将我的模型转换为该对象,使用稍作修改的 Memento 设计模式版本。

在您的代码库中,您可以将 Memento 类添加到您的原始数据类(假设您的数据类是 Data)。你的纪念品类可以是Data.MementoDataMemento,一个单独的类。您的 memento 类应该包含与数据类相同的字段(不过,您可以忽略不会持久化的 volatile 变量)。

您可以使用类似的代码在 Room 进行序列化和反序列化期间来回转换这两种类型。

public DataMemento toMemento() {
    return new DataMemento(/* parameters of your memento's constructor */);
}

public static Data fromMemento(DataMemento code) {
    return new Data(/* parameters of your entity's constructor */);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-09
    • 2014-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    相关资源
    最近更新 更多