由于一些原因,我通常避免让类知道如何序列化自身。首先,如果要与其他格式反序列化,现在需要使用额外的逻辑来污染模型。如果通过接口访问模型,那么还会污染合同。
public class Image
{
public void toJPG(String filePath) { ... }
public Image fromJPG(String filePath) { ... }
}
但是,如果您想将其序列化到PNG和GIF,或从PNG和GIF序列化呢?现在班级变成
public class Image
{
public void toJPG(String filePath) { ... }
public Image fromJPG(String filePath) { ... }
public void toPNG(String filePath) { ... }
public Image fromPNG(String filePath) { ... }
public void toGIF(String filePath) { ... }
public Image fromGIF(String filePath) { ... }
}
相反,我通常喜欢使用类似于以下内容的模式:
public interface ImageSerializer
{
void serialize(Image src, Stream outputStream);
Image deserialize(Stream inputStream);
}
public class JPGImageSerializer : ImageSerializer
{
public void serialize(Image src, Stream outputStream) { ... }
public Image deserialize(Stream inputStream) { ... }
}
public class PNGImageSerializer : ImageSerializer
{
public void serialize(Image src, Stream outputStream) { ... }
public Image deserialize(Stream inputStream) { ... }
}
public class GIFImageSerializer : ImageSerializer
{
public void serialize(Image src, Stream outputStream) { ... }
public Image deserialize(Stream inputStream) { ... }
}
现在,在这一点上,这种设计的注意事项之一是,序列化程序需要知道要identity
序列化的对象的。有人会说这是不好的设计,因为实现泄漏到了类之外。风险/报酬实际上取决于您,但是您可以稍微调整课程以做类似的事情
public class Image
{
public void serializeTo(ImageSerializer serializer, Stream outputStream)
{
serializer.serialize(this.pixelData, outputStream);
}
public void deserializeFrom(ImageSerializer serializer, Stream inputStream)
{
this.pixelData = serializer.deserialize(inputStream);
}
}
这更像是一个一般的例子,因为图像通常都带有元数据。诸如压缩级别,色彩空间等之类的东西可能会使过程复杂化。