Por lo general, evito que la clase sepa cómo serializarse, por un par de razones. Primero, si desea (des) serializar a / desde un formato diferente, ahora necesita contaminar el modelo con esa lógica adicional. Si se accede al modelo a través de una interfaz, también contaminará el contrato.
public class Image
{
public void toJPG(String filePath) { ... }
public Image fromJPG(String filePath) { ... }
}
Pero, ¿qué pasa si desea serializarlo a / desde un PNG y GIF? Ahora la clase se convierte
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) { ... }
}
En cambio, normalmente me gusta usar un patrón similar al siguiente:
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) { ... }
}
Ahora, en este punto, una de las advertencias con este diseño es que los serializadores necesitan conocer identity
el objeto que está serializando. Algunos dirían que este es un mal diseño, ya que la implementación se filtra fuera de la clase. El riesgo / recompensa de esto depende realmente de usted, pero podría modificar ligeramente las clases para hacer algo como
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);
}
}
Este es más un ejemplo general, ya que las imágenes generalmente tienen metadatos que lo acompañan; cosas como el nivel de compresión, el espacio de color, etc., que pueden complicar el proceso.