J'évite généralement que la classe sache comment se sérialiser, pour plusieurs raisons. Tout d'abord, si vous souhaitez (dé) sérialiser vers / à partir d'un format différent, vous devez maintenant polluer le modèle avec cette logique supplémentaire. Si le modèle est accessible via une interface, vous polluez également le contrat.
public class Image
{
public void toJPG(String filePath) { ... }
public Image fromJPG(String filePath) { ... }
}
Mais que se passe-t-il si vous souhaitez le sérialiser vers / depuis un PNG et un GIF? Maintenant, la classe devient
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) { ... }
}
Au lieu de cela, j'aime généralement utiliser un modèle similaire au suivant:
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) { ... }
}
Maintenant, à ce stade, l'une des mises en garde avec cette conception est que les sérialiseurs doivent connaître identity
l'objet de la sérialisation. Certains diront que c'est une mauvaise conception, car l'implémentation fuit en dehors de la classe. Le risque / récompense de cela dépend vraiment de vous, mais vous pouvez légèrement modifier les cours pour faire quelque chose comme
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);
}
}
Il s'agit plus d'un exemple général, car les images ont généralement des métadonnées qui vont avec; des choses comme le niveau de compression, l'espace colorimétrique, etc. qui peuvent compliquer le processus.