序列化逻辑应该在实体还是其他类中
应该在何处放置对象序列化逻辑(字段到XML或JSON名称和值的映射)? 在每个实体对象内部或者只是与序列化有关的一组不同的类? 那个与这个问题有关的其他最佳实践?
例如:
class Person { String name; }
有些人这样做:
class Person { String name; public String toJson () { // build JSON, use 'name' field } }
但是,如果我们还需要XML(),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方法。 他们声称更简单,更不容易出错。
什么是首选方式,是否有更好的替代方案来实现此问题的解决方案?
我会说序列化逻辑不应该是POCO /数据类的一部分,原因有很多:
- 单一责任原则(数据类应该只定义数据模型,注意序列化逻辑)
- 你可能需要不同种类的序列化器(如你所提到的json / xml等)
- 序列化实现大多数时候是通用解决方案或外部包。 即使您想要某些对象的自定义实现,您仍然可以使用通用解决方案来扩展特定类,因此不需要为每个类提供它。
- 您可以使用属性来装饰POCO类,以指示序列化程序处理特殊条件(例如控制属性序列,属性名称甚至是复杂类型属性的客户序列化程序)
还有其他原因,但有一些强有力的论据,为什么你不应该将序列化逻辑放入你的POCO /数据模型。
使用序列化的自定义JSON对象非常简单。
我在我的项目中写了一个claas,我给你一个如何在Projects中实现它的线索
申请(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 { @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(); } } }