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

时间:2016-02-24 03:43:36

标签: java json design-patterns serialization pojo

应该放置对象序列化逻辑(将字段映射到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
    }
}

然后工厂根据实体类型分发Serializers:

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

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

2 个答案:

答案 0 :(得分:3)

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

  1. 单一责任原则(数据类应仅定义数据模型,注意序列化逻辑)
  2. 您可能需要不同类型的序列化程序(如您所述,json / xml等)
  3. 序列化实现大多数时候是通用解决方案或外部包。即使您想要为某些对象进行自定义实现,您仍然可以使用通用解决方案来扩展特定类,因此不需要为每个类提供它。
  4. 您可以使用属性来装饰POCO类,以指导序列化程序处理特殊条件(例如控制属性序列,属性名称甚至是复杂类型属性的客户序列化程序)
  5. 还有其他原因,但有一些强有力的论据,为什么你不应该将序列化逻辑放入你的POCO /数据模型。

答案 1 :(得分:-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;
}
  

现在包含Customization的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();
        }
    }
  }