当前位置: 首页 > 面试题库 >

序列化逻辑应该在实体还是其他类中

冯飞鹏
2023-03-14
问题内容

对象序列化逻辑(字段到XML或JSON名称和值的映射)应放在何处?在每个实体对象内部,或者进入仅涉及序列化的一组不同的类?还有其他与此问题相关的最佳做法吗?

例如:

class Person {
    String name;
}

有些人这样处理:

class Person {
    String name;
    public String toJson () {
      // build JSON, use 'name' field
    }
}

但是,如果我们还需要toXML(),toCSV(),toXYZ()保持该方向,则会创建受污染严重的代码,并破坏单一责任原则,即使使用单个toJson方法IMHO也已被打破。

另一个选择,这是我通常要做的:

interface Serializer {  public String toJson (); }

class PersonJsonSerializer implements Serializer {
    private Person p;
    public PersonJsonSerializer (Person p) { this.person = p; }
    public String toJson () {
      // build JSON, use p.name
    }
}

然后工厂根据实体类型派发序列化器:

class JsonSerializerFactory {
    public Serializer getSerializer (Object o) {
        if (o instanceof Person) {
            return new PersonJsonSerializer ((Person)o);
        }
        else if (o instanceof Account) {
            return new AccountJsonSerializer ((Account)o);
        }
        // ... etc
    }
}

也将有XMLSerializerFactory,CSVSerializerFactory等。

但是,大多数时候,人们希望对序列化有完全的控制权,而不愿意花钱购买它,而更喜欢在每个类中使用toJson方法。他们认为这是更简单且更不易出错的方式。

首选的方式是什么,是否有更好的替代方法来实现此问题的解决方案?


问题答案:

我要说,由于许多原因,序列化逻辑不应成为POCO /数据类的一部分:

  1. 单一责任原则(数据类仅应定义数据模型,注意序列化逻辑)
  2. 您可能需要不同类型的序列化器(如您提到的html" target="_blank">json / xml等)
  3. 大多数时候,序列化实现是通用解决方案或外部程序包。即使您希望对某些对象进行自定义实现,您仍然可以拥有一个通用解决方案,可以将其扩展为特定的类,因此无需为每个类都拥有它。
  4. 您可以用属性装饰POCO类,以在特殊情况下指导序列化程序(例如控制属性,属性名称的序列,甚至控制复杂类型属性的客户序列化程序)

也有其他原因,但是有一些强烈的理由为什么您不应该将序列化逻辑放入POCO /数据模型中。



 类似资料:
  • 我试图保持传统,这就是为什么我最近几天在一个Android项目中重构一些Kotlin代码的原因。我查看了许多Room实体数据类示例,但仍然没有获得在Room上下文中使用val/var的最佳实践。我认为合适的方法应该是val,因为它位于持久层,应该创建关于这些实体的DTO(数据传输对象),这些实体可以修改。有人能保证或否认这个假设吗!?

  • 问题内容: 我们正在考虑用JSON(WCF或其他)调用替换(一些或许多)“经典” SOAP XML WCF调用,因为其开销较低且易于直接在Javascript中使用。现在,我们刚刚在Web服务中添加了一个额外的Json端点,并在某些操作中添加了WebInvoke属性并对其进行了测试。使用C#.Net客户端或Javascript客户端,一切正常。到目前为止,一切都很好。 但是,似乎将大JSON字符串

  • 嗨,我在声纳皮棉中收到此错误: “Serializable”类中的字段应该是暂时的或可序列化的 私有最终条件notEmpty=锁定。newCondition() 我的代码是: 有人能提供解决方案,使sonar不会显示所有三个变量的这些错误吗?

  • 整体逻辑 整体逻辑如下图所示。

  • 问题内容: log4j网络适配器将事件作为序列化的Java对象发送。我希望能够捕获此对象并以另一种语言(python)将其反序列化。这可能吗? 注意 网络捕获很容易;它只是一个TCP套接字并在流中读取。困难是反序列化部分 问题答案: 通常,不会。 本文档中定义了Java序列化的流格式,但是您需要访问原始类定义(以及将它们加载到Java运行时中)以将流数据转换回接近原始对象的内容。例如,类可以定义w

  • 我正在创建一个web程序,用spring boot、tomcat和JPA映射商店的占有率。我已经创建了成员模型/服务/控制器,当我尝试更新、创建、删除它或从中获取信息时,它工作正常。 然而,商店也没有被创建,当我用ownerId创建一个商店时,我会收到一条错误消息,说: 错误消息 [org.springframework.http.converter.httpMessageEndableExcep