【问题标题】:Should serialization logic be in the entity or other class序列化逻辑是否应该在实体或其他类中
【发布时间】:2016-02-24 03:43:35
【问题描述】:

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

例如:

class Person {
    String name;
}

有些人是这样处理的:

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

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

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

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 方法。他们会声称更简单,更不容易出错。

首选的方法是什么,是否有更好的替代方案来解决这个问题?

【问题讨论】:

  • 当标准库(如 JAXB、Jackson 等)存在时,为什么要滚动您自己的序列化逻辑?
  • 我同意你的看法。问题是,有时您对可用选项不够熟悉,或者时间有限并且被分配了紧迫的截止日期,或者仅仅是因为从永无止境的选项海洋中找到“正确”的库导致分析瘫痪,并且您决定开始编码会更好。但我同意——没有必要重新发明轮子。

标签: java json design-patterns serialization pojo


【解决方案1】:

我会说序列化逻辑不应该是 POCO/数据类的一部分,原因有很多:

  1. 单一职责原则(数据类应该只定义数据模型,注意序列化逻辑)
  2. 您可能需要不同种类的序列化程序(如您提到的 json/xml 等)
  3. 序列化实现大部分时间是通用解决方案或外部包。即使您想为某些对象自定义实现,您仍然可以拥有一个通用解决方案,您可以为特定类扩展它,因此无需为每个类都提供它。
  4. 您可以使用属性装饰您的 POCO 类,以指导序列化程序处理特殊条件(例如控制属性序列、属性名称,甚至是复杂类型属性的客户序列化程序)

还有其他原因,但有一些强有力的论据说明为什么您不应该将序列化逻辑放入您的 POCO/数据模型中。

【讨论】:

    【解决方案2】:

    使用序列化自定义 JSON 对象非常简单。

    我在我的项目中写了一个 claas,我正在给你一个线索,告诉你如何在项目中实现它

    应用程序(POJO 类)

     import java.io.Serializable;
     import java.util.List;
     import org.webservice.business.serializer.ApplicationSerializer;
     import com.fasterxml.jackson.databind.annotation.JsonSerialize; 
    
    @JsonSerialize(using=ApplicationSerializer.class)
      public class Application  implements Serializable {
    
    private static final long serialVersionUID = 1L;
    private double amount;
    private String businessType;
    private String currency;
    private int duration;
    }
    

    现在包含自定义的 LoanApplicationSerializer 类 使用序列化逻辑......

     package org.webservice.business.serializer;
    
      import java.io.IOException;
      import org.webservice.business.dto.Application;
      import com.fasterxml.jackson.core.JsonGenerator;
      import com.fasterxml.jackson.core.JsonProcessingException;
      import com.fasterxml.jackson.databind.JsonSerializer;
      import com.fasterxml.jackson.databind.SerializerProvider;
    
     public class ApplicationSerializer extends JsonSerializer<Application> {
    
    @Override
    public void serialize(Application prm_objObjectToSerialize, JsonGenerator prm_objJsonGenerator, SerializerProvider prm_objSerializerProvider) throws IOException, JsonProcessingException {
        if (null == prm_objObjectToSerialize) {
        } else {
            try {
                prm_objJsonGenerator.writeStartObject();
    
                prm_objJsonGenerator.writeNumberField("amount", prm_objObjectToSerialize.getAmount());               
                prm_objJsonGenerator.writeNumberField("duration", prm_objObjectToSerialize.getDuration());
                prm_objJsonGenerator.writeStringField("businesstype", prm_objObjectToSerialize.getBusinessType());
                prm_objJsonGenerator.writeStringField("currency", prm_objObjectToSerialize.getCurrency());
    
    
            } catch (Exception v_exException) {
                v_exException.printStackTrace()
            } finally {
                prm_objJsonGenerator.writeEndObject();
            }
        }
      }
    

    【讨论】:

      猜你喜欢
      • 2023-02-23
      • 1970-01-01
      • 2016-02-25
      • 2012-12-06
      • 1970-01-01
      • 2020-03-15
      • 2020-02-19
      • 2018-05-03
      • 1970-01-01
      相关资源
      最近更新 更多