Где должна быть размещена логика сериализации объектов (отображение полей в имена и значения 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 внутри каждого класса. Они утверждают, что это намного проще и менее подвержено ошибкам.

Каков предпочтительный путь и есть ли лучшие альтернативы для решения этой проблемы?

5
Jose Cifuentes 24 Фев 2016 в 06:43

2 ответа

Лучший ответ

Я бы сказал, что логика сериализации не должна быть частью классов POCO / data по многим причинам:

  1. Принцип единой ответственности (классы данных должны определять только модель данных, обратите внимание на логику сериализации)
  2. Могут быть разные типы сериализаторов, которые вам могут потребоваться (json / xml и т. Д., Как вы упомянули)
  3. Реализация сериализации в большинстве случаев представляет собой универсальное решение или внешний пакет. Даже если вам нужна индивидуальная реализация для некоторых объектов, вы все равно можете иметь универсальное решение, которое можно расширить для определенных классов, поэтому нет необходимости иметь его для каждого класса.
  4. Вы можете украсить свои классы POCO атрибутами, чтобы направлять сериализатор для особых условий (например, для управления последовательностью свойств, имен свойств или даже сериализатором клиента для свойств сложного типа)

Могут быть и другие причины, но есть несколько веских аргументов, почему вы не должны помещать логику сериализации в свою POCO / модель данных.

6
Naeem 24 Фев 2016 в 03:57

Настроить объект JSON с использованием сериализации очень просто.

Я написал класс в своем проекте, я даю вам подсказку, как реализовать это в проектах

Приложение (класс 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();
        }
    }
  }
-2
Vikrant Kashyap 24 Фев 2016 в 05:18