In genere evito che la classe sappia come serializzare se stessa, per un paio di motivi. Innanzitutto, se vuoi (de) serializzare su / da un formato diverso, ora devi inquinare il modello con quella logica extra. Se si accede al modello tramite un'interfaccia, si inquina anche il contratto.
public class Image
{
public void toJPG(String filePath) { ... }
public Image fromJPG(String filePath) { ... }
}
Ma cosa succede se vuoi serializzarlo su / da un PNG e GIF? Ora la classe diventa
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) { ... }
}
Invece, in genere mi piace usare un modello simile al seguente:
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) { ... }
}
Ora, a questo punto, uno degli avvertimenti con questo motivo è che i serializzatori hanno bisogno di conoscere l' identity
dell'oggetto è serializzazione. Alcuni direbbero che questo è un cattivo design, in quanto l'implementazione perde fuori dalla classe. Il rischio / la ricompensa di questo dipende solo da te, ma potresti modificare leggermente le classi per fare qualcosa di simile
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);
}
}
Questo è più di un esempio generale, in quanto le immagini di solito hanno metadati che lo accompagnano; cose come livello di compressione, spazio colore, ecc. che possono complicare il processo.