CSC/ECE 517 Fall 2009/wiki2 18 ee: Difference between revisions
Line 73: | Line 73: | ||
During serialization, the following occurs: | During serialization, the following occurs: | ||
# The object is checked to see if writeReplace() is defined for the Person object. | |||
# The writeReplace() function is called to retrieve the proxy object. | |||
# Serialization takes place on the proxy object instead. | |||
=== Deserialization === | === Deserialization === |
Revision as of 23:33, 8 October 2009
Serialization Proxy Design Pattern
During system design, immutable classes are preferred to guarantee thread safety and consistent object state. For instance, serialization of immutable classes could cause issues in Java if immutability must be preserved. The Serialization Proxy Pattern aims to make serialization acceptable in that regard. Discuss serialization proxy pattern with regards to the problem, design, implementation details, and idiomatic usage.
Introduction
When the need to serialize objects in Java arises, the most common tool is the Serializable interface. This interface is simply used to indicate that the object is serializable. The class may implement the writeReplace() method. If it does, during serialization the object returned from this method will be used for serialization instead of the object itself.
The Problem
One issue with serialization under Java is the need for serialization of immutable classes. Take the following class for example:
public class Person { String name; Integer age; public Person(String name, Integer age) { this.name = name; this.age = age; } public String name() { return name; } public Integer age() { return age; } }
The class is easily serializable with no changes, and could be written to disk easily. A problem arises when the object needs to be deserialized. Normally when Java is deserializing an object, it would call the default constructor Person() and then call setFoo() on each object attribute. With this object there is no default constructor, nor are there setters for the object's attributes. This is where the Serialization Proxy pattern comes into play.
The Proxy Object
To work around the fact that we can't deserialize an immutable class, we use a proxy object that is an inner class of the class we want to serialize. We would change the person class as follows:
public class Person { private String name; private Integer age; public Person(String name, Integer age) { this.name = name; this.age = age; } public String name() { return name; } public Integer age() { return age; } private Object writeReplace() { return new Proxy(this); } private static class Proxy implements Serializable { String name; Integer age; public Proxy() { } public Proxy(Person person) { name = person.name(); age = person.age(); } Object readResolve() { return new Person(name, age); } } }
So what changed? A private static class was added that is Seriazliable and holds all the same information as the Person class.
Serialization
During serialization, the following occurs:
- The object is checked to see if writeReplace() is defined for the Person object.
- The writeReplace() function is called to retrieve the proxy object.
- Serialization takes place on the proxy object instead.
Deserialization
During deserialization, the following occurs:
- The Proxy object is deserialized, resulting in a Proxy object. Since the member variables of the Proxy object are public, it can be deserialized with no issue.
- The Proxy object is examined to determine if it has a readResolve() method.
- Since it does, readResolve() is called, returning a new Person immutable object.
Definitions
- serialization - deserialization - imitable - thread safety
References
http://stackoverflow.com/questions/702357/what-is-the-serialization-proxy-pattern http://lingpipe-blog.com/2009/08/10/serializing-immutable-singletons-serialization-proxy/