CSC/ECE 517 Fall 2009/wiki2 18 cc: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
 
(162 intermediate revisions by the same user not shown)
Line 1: Line 1:
==''' PROXY SERIALIZABLE PATTERN'''==
==Introduction and Objective==


==Introduction==
Immutable classes are used to ensure the object state never gets changed. On the other hand the concept of serialization is that applications can send and receive objects across the network; this is a step further than just keeping the object alive (persistence), which is the ability to call objects remotely, however '''private instances may be exposed by performing serialization'''.


Immutable classes are used to ensure the object state never change.
Now the problem arises when serializing an immutable class and the immutability must be preserved between applications. There is a nice description of this problem in the [http://stackoverflow.com/questions/702357/what-is-the-serialization-proxy-pattern stackoverflow.com Forum ]
The concept of serialization is that applications can send and receive objects between them; this is a step further than just keeping the object alive (persistence) which is to call objects remotely, however private instances may be exposed by performing serialization.
Now the problem arises when serializing an immutable class and the immutability must be preserved between applications.  


The Serialization Proxy Pattern tries to handle this kind of situation, the deliverables of this wiki are:
The '''Serialization Proxy Pattern''' is capable to handle this kind of situations; henceforth the main objectives are to explain:
1. Investigate how the issue described above is handled.
2. Investigate how it is designed and give details of its implementation,
3. Investigate its idiomatic usage


==Definitions==
* 1. It's idiomatic usage.


===When a class is immutable?===
* 2. How it is designed and gives details of its implementation.
If a class state cannot be modified after being created then it is called immutable, and viceverza a mutable class can be modified after being created. There are also partially immutable classes, in which some of their attributes can be defined as immutable.  


The following is an example to illustrate it:
* 3. How the issue described above is handled.


        String  course_id= "ECE517";
==When a Class is Immutable?==
        course_id.toLowerCase();


In this case the string didn’t change to lower case, it remains as “ECE517”, although the output is “ece517”, instead the output is a new string that can be assigned to other variable, therefore for the moment the values are still immutable, however the following code can change the value.
If a class state cannot be modified after being created then it is called '''immutable''', on the contrary a '''mutable''' class can be modified after being created. There are also '''partially immutable''' classes, in which some of their attributes can be defined as immutable.  


        course_id =  course_id.toLowerCase();
The key advantage is that they cannot be corrupted since the state cannot be changed.


===How to make a class immutable?===
To learn more about Immutable classes refer to the  [http://java.sun.com/docs/books/tutorial/essential/concurrency/immutable.html Java.sun.com Immutable Tutorial]
Henceforth to make a class immutable we need to keep the class state safe by any means, in other words, assignments should never occur, the following code is an example of immutable class
 
       
 
        final class Immutable_ece517Class  
The following is an example to illustrate immutable property:
        {  
 
        // To make the variables private and the term “final” is to restrict writing 
  String  course_id= '' "ECE517" '';
            private final string nombre;  
  course_id.toLowerCase();
       
 
        // Constructor where we can provide the constant value  
In this case the ''course_id'' didn’t change to lower case, it remains as '' "ECE517" '', although the output is '' “ece517" '', instead the output is a new string that can be assigned to another variable, therefore and for the moment the values are still immutable, however the following code can change the value.
            public Immutable_ece517Class (string paramNombre)  
 
            {  
  course_id =  course_id.toLowerCase();
              nombre = paramNombre;  
 
            }  
==How to Make a Class Immutable?==
       
 
        // Define the methods to return variable value without writing it  
====Java Example====
            public string getNombre
 
            {  
To make a class '''immutable''' we need to keep the class state safe by any means, in other words, assignments should never occur, the following code is an example of immutable class in ''JAVA''
              return nombre;  
 
             }  
  final class Immutable_ece517Class  
  {  
      // To make the variables private use the term ''final''
      '''final''' string nombre;  
      // Constructor where we can provide the constant value  
      public Immutable_ece517Class (string paramNombre)  
      {  
        nombre = paramNombre;  
      }  
      // Define the methods to return variable
      public string getNombre
      {
        return nombre;
      }
  }
See other examples in [http://en.wikipedia.org/wiki/Immutable_class#Java wiki/Immutable_class#Java]
 
The trick here is that '''final''' before the variable restricts to write to private variables, the method after that is only to read the variable value without writing it.
 
====Ruby Example====
 
To implement '''immutable''' class in ''Ruby'', the programmer must use the ''Struct.immutable'' instead of using ''Struct.new'', the following is the code example implementation.
 
  def Struct.immutable(*args)  # Factory method for immutable classes
    Struct.new(*args).class_eval do # Define struct, then modify it
      undef []=                    # Un-define general mutation
      args.each do |sym|            # For each field of the struct
        mutator = :"#{sym.to_s}="  # Symbol for setter method
        remove_method mutator      # Un-define that method
      end
      self                          # Return the class
    end
  end
 
Visit [http://rubylearning.com/satishtalim/mutable_and_immutable_objects.html mutable and immutable objects in Ruby] for other examples
 
It is recommended to visit [http://en.wikipedia.org/wiki/Immutable_class Wiki/Immutable Code], in there you can find immutable implementations in other languages.
 
==What is Serialization?==
It is known as the process from a source application to convert an object into a sequence of bits and to store or sent them through the network, in this way the same sequence can be retrieved by another end application that '''reconstructs''' or '''clones''' the original object in order to use it, this capability to store entire objects instead of simple parameters make possible to have high level distributed applications, without '''serialization''' the object would persist only while it is being executed (transient) and the application interaction would not be possible, e.g. remote procedure calls. Figure 1 Shows the '''Serialization/De-serialization''' process.
 
 
[[Image:serialization.JPG |1000px|]]
    '''    Figure 1. The process of Serialization/De-serialization'''
 
 
There is an option when an object is '''serialized''', the state can also recorded in the byte stream, when it is retrieved its last state is also recovered, this feature allow the possibility to save the object state in memory and retrieve for its use later by the same application, the details to implement this feature are discussed in ''Proxy Serialization'' section, although there is also an application named as '''persistent''' that does the same, '''serialization''' can be also used as a persistent procedure to keep alive classes in local memory storage after being executed.
 
It is also possible to serialize complex data structures like applets and complete GUI (Graphical User Interface), but the scope of this wiki will be on class '''serialization''' only.
 
To have an insight on Serialization we recommend to visit [http://en.wikipedia.org/wiki/Serialization wiki/Serialization ]
 
==How to Implement Serialization of Classes?==
 
===Java Serialization===
The next step would be in how to implement '''serialization''' of classes. In this case Java.io package offers the ''“writeObject()”'' to serialize and for un-serialize it uses ''“readObject( )”'' both are methods from ''ObjectOuputStream'' and ''ObjectOuputStream'' respectively, for an object to be serialized must have implemented the ''java.io.Serializable'' interface, the reason behind this is security, some private classes should not be exposed when de-serialize them, this is why a class must explicitly declare as serialize.
 
Below is the serialization code implementation in '''JAVA''': taken from [http://en.wikipedia.org/wiki/Serialization#Example_2  wiki/Object_serialization#java]
 
  import java.io.*;
  /* The object to serialize. */
  class ObjectToSerialize implements Serializable {
      static private final long serialVersionUID = 42L;
      private String firstAttribute;
      private int secondAttribute;
      public ObjectToSerialize(String firstAttribute, int secondAttribute) {
          this.firstAttribute = firstAttribute;
          this.secondAttribute = secondAttribute;
      }
      @Override
      public String toString() {
          return firstAttribute + ", " + secondAttribute;
      }
  }
    public static void main(String[] args) {
        ObjectToSerialize original = new ObjectToSerialize("some text", 123);
        System.out.println(original);
        try {
            saveObject(original, "object.ser");
            ObjectToSerialize loaded = (ObjectToSerialize) loadObject("object.ser");
             System.out.println(loaded);
        } catch (Exception e) {
            e.printStackTrace();
         }
         }
    }
  }


The final statemente makes it immutable *****************
===Ruby Serialization===


===What is Serialization?===
Ruby uses the methods of ''dump'' and ''load'' from the '''Marshal''' module to perform '''serialization''', however not all objects can be serialized, the exeptions are ''Bindings'', ''Procedures'' and ''Singleton'' objects,  
It is known as the process from a source application to convert an object into a sequence of bits and to store or sent them through the network, in this way the same sequence can be retrieved by another end application, it reconstructs or “clones” the original object in order to use it, this capability to store entire objects instead of simple parameters make possible to have high level distributed applications, without them the object would persist only while it is being executed (transient) and the application interaction would not be possible, e.g. remote procedure calls.


When an object is serialized its state is also recorded in the byte stream, when it is retrieved its last state is also recovered, this feature allow the possibility to save the object state in memory and retrieve for its use later by the same application, although there is also an application named as persistent that does the same, serialization can be also used as persistent object
Below is the code implementation in '''Ruby''', taken from [http://en.wikipedia.org/wiki/Object_serialization#Ruby wiki/Object_serialization#Ruby]


It is also possible to serialize complex data structures like applets and complete GUI, but the scope of this wiki will be on the classes serialization.  
  class Klass
    def initialize(str)
      @str = str
    end
    def sayHello
      @str
    end
  end
 
  o = Klass.new("hello\n")
  data = Marshal.dump(o)
  obj = Marshal.load(data)
  obj.sayHello  »  "hello\n"


===How to serialize classes?===
==The Main Issue when De-serialize an Immutable Class ==
The weakness in '''serialization''' is that the details of the hidden private instances may be exposed in the other end application which is not good, however in order to make remote call the end application must understand the de-serialized objects, this is why serialization formats have been developed to keep proprietary software, one clear example is that a '''password and login should never be serialized''', it is too risky if this information is exposed in the form of a serialized variable class.


=====Java Serialization=====
The next step would be in how to serialize classes. In this case Java.io package offers the “writeObject()” to serialize and for un-serialize it uses “readObject( )” both are methods from ObjectOuputStream and ObjectOuputStream respectively, for an object to be serialized must have implemented the java.io.Serializable interface, the reason behind this is the security, some private classes should not be exposed when un-serialize them, this is why a class must explicity declare as serializable, Below is the code implementation in JAVA for serialization:


Link from http://en.wikipedia.org/wiki/Immutable_class don’t forget it
The main issue is '''that hidden private instances (immutable classes) can be exposed when de-serialize''' in the other end application and the idea is that they must remain safe and unchanged across applications. The solution proposed is the use of the '''Proxy Serialization Pattern.'''


===== Example in Java =====
       
        import java.io.*;
       
        /**
        * The object to serialize.
        */
        class ObjectToSerialize implements Serializable {
            static private final long serialVersionUID = 42L;
       
            private String firstAttribute;
            private int secondAttribute;
       
            public ObjectToSerialize(String firstAttribute, int secondAttribute) {
                this.firstAttribute = firstAttribute;
                this.secondAttribute = secondAttribute;
            }
       
            @Override
            public String toString() {
                return firstAttribute + ", " + secondAttribute;
            }
        }
       
        public class Main {
            /**
            * Saves an object.
            */
            private static void saveObject(Serializable object, String filename) throws IOException {
                ObjectOutputStream objstream = new ObjectOutputStream(new FileOutputStream(filename));
                objstream.writeObject(object);
                objstream.close();
            }
       
            /**
            * Loads an object.
            */
            private static Object loadObject(String filename) throws ClassNotFoundException, IOException {
                ObjectInputStream objstream = new ObjectInputStream(new FileInputStream(filename));
                Object object = objstream.readObject();
                objstream.close();
                return object;
            }
       
            public static void main(String[] args) {
                ObjectToSerialize original = new ObjectToSerialize("some text", 123);
                System.out.println(original);
                try {
                    saveObject(original, "object.ser");
                    ObjectToSerialize loaded = (ObjectToSerialize) loadObject("object.ser");
                    System.out.println(loaded);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }


=====Ruby Serialization=====
You can find an alternate description of the problem or main issue written very well in a blog by [http://stackoverflow.com/questions/702357/what-is-the-serialization-proxy-pattern  "Bob Carpenter" Alias]
 
==What is a Proxy Pattern?==
The '''Proxy Pattern''', which is one of the most used design patterns, defines a proxy object that interacts between source and sink applications within a network, one common use of it is the ability to call a remote tasks and to share information trough a network.
 
 
To learn more on this topic please visit [http://en.wikipedia.org/wiki/Proxy_pattern Wiki/Proxy Pattern]
 
 
There are two most common types of proxies:
 
The first one is '''virtual proxy''' which creates the proxy object that interacts with the same application or other application within the same computer (stored in local memory), its purpose is to keep an object state alive after its execution so that it can be used later on.
 
The second one is '''remote proxy''' which creates the proxy object to be used in a different address space, commonly in a remote object on a distant host. It creates the illusion of interacting with the object or task directly, however there is a proxy between them that makes the interaction possible.
 
==So, What is Proxy Serialization Pattern?==
In general and summarized, the '''proxy serialization''' means that a class is ''serialized'' along with the method ''“writeReplace()”'' (Java), the result of this procedure is the so called '''“proxy serialization”''', on the other end side the class is ''de-serialized'' along with the method ''“readResolve()”'' (Java) to reconstruct the class state (private properties).


Ruby uses the methods of dump and load from the Marshal module, but not all object can be serialized like bindings, Procedures and singleton objects,
The process to make a Proxy Serialization in more detail is listed below:


Below is the code implementation in Ruby for serialization.
       
        class Klass
          def initialize(str)
            @str = str
          end
          def sayHello
            @str
          end
        end
       
        o = Klass.new("hello\n")
        data = Marshal.dump(o)
        obj = Marshal.load(data)
        obj.sayHello  »  "hello\n"


The weakness in serialization is that the details of the hidden private instances may be exposed in the other end application which is not good, however in order to make remote call the end application must understand the objects, this is why serialization formats have been developed to keep proprietary software, one clear example is that a password and login should never be serialized, it is too risky if this information is exposed in the form of a serialized variable class.
1. Before class '''serialization''' takes place, Java checks if the class contains the method ''“Object writeReplace()”''.


==The Main issue when de-serialization ==
2. If it does then the return value of ''“Object writeReplace()”'' is serialized together with the class (called '''Proxy Serialization'''), other wise only perform normal ''serialization'' on the class.
The issue is that hidden private instances (immutable classes) can be exposed in the other end application and the idea is that they must remain safe and unchanged across applications. The solution proposed is the use of the Proxy Serialization Pattern


3. The '''proxy serialized value''' is used to keep the state of the original object to write (e.g. ''immutability''), so that in the other end application the state can be recovered.


===So, What is Proxy Serialization Pattern?===
4. When de-serializing, Java checks if the class has the implementation of the method '''“Object readResolve()”''' if it does then it completes the ''de-serialization'' process and then the return value of the '''“readResolve()”''' is added to the ''de-serialization'', which contains the state of the original object to write (e.g. immutability)
In general and summarized, the proxy serialization means that a class is serialized along to the method “writeReplace()” (Java), the result of this procedure is the so called “serialization proxy”, on the other end side the de-serialization process uses the “readResolve()” (Java), and the common de-serialization to reconstruct the class.


The process to make a Proxy Serialization in detail is listed below:
1. Before the serialization Java checks if the class contains the method “Object writeReplace()”.
2. If it does contain it then the return value of “Object writeReplace()” is serialized together with the class (called “Proxy Serialization”), other wise only perform normal serialization on the class.
3. The proxy serialized value is used to keep the state of the original object to write (e.g. immutability), so that in the other end application it can be reconstituted such state.
4. When de-serializing, Java checks if the class has the implementation of the method “Object readResolve()” if it does then it completes the de-serialization process and then the return value of the “readResolve()” is added to the  de-serialization, which contains the state of the original object to write (e.g. immutability)


Figure 2 shows the process of Proxy Serialization Pattern
[[Image:Proxy.jpg|1000px|]]
[[Image:Proxy.jpg|1000px|]]


==How does Proxy Serilaization Pattern Handles the De-serialization Issue==
    '''    Figure 2. The process of Proxy Serialization/De-serialization'''
 
To Learn more refer to Chapter 11, item 76 of the book [http://www.amazon.com/Effective-Java-2nd-Joshua-Bloch/dp/0321356683 Effective Java (2nd Edition)], '''Joshua Bloch''' Author
 
 
The key advantage of '''Proxy Serialization process is that proxy is implemented as a private static nested class''', in figure 2 shows that its state is serialized (control of the read/write process) as well as the class itself, on the other end side the state is de-serialized (control of the read/write process) along with the class, '''in this way the class state is kept in the cloned class''', this would keep the properties for example of an immutable implementation class.
 
==Proxy Serialize Implementation in JAVA==
 
The following code shows an example in Java; the first one is a typical immutable class, the second one is the serialization proxy implemented.
 
===Typical Immutable Class===
 
  public class Tot_price {
      final int mPrice;
      final int mTax;
      public int price() { return mPrice; }
      public int tax() { return mTax; }
      public int total() {
      return price() + tax();
  }
 
===Typical Immutable with Class Proxy Serialization===
 
The following code was inspired by the JAVA code in [http://lingpipe-blog.com/2009/08/10/serializing-immutable-singletons-serialization-proxy/ Serialization Proxy LingPipe]


The key advantage of Proxy Serialization process is that proxy is implemented as a private static nested class, figure 1 shows that its state is serialized (control of the read/write process) as well as the class itself, on the other end side the state is de-serialized (control of the read/write process) along with the class, in this way the class state is kept in the cloned class, this would keep the properties for example of an immutable implementation class.
  public class Tot_price implements Serializable {
      private final mPrice;
      private final mTax;
      public Tot_price(double price, double tax) { mPrice = price; mTax=tax; }
      ...
      private Object writeReplace() {
          return new SerializationProxy(this);
      }
     
      private static class SerializationProxy
          implements Serializable {
          int mPrice; int mTax;
          public SerializationProxy() { }
          public SerializationProxy(Tot_price cost) {
              mPrice = cost.price();  mTax = cost.tax();
          }
          Object readResolve() {
              return new Tot_price(mPrice,mTax);
          }
      }
  }


The following code shows an example in Java; the first one is a typical immutable class, the second one is the same class with serialization proxy implemented
===Proxy Serialization Identification===
Immutable Class
A random serial ID number is added whenever a class is ''Proxy Serialized'' by default. However, it is highly recommended to add it within the code in order to preserve forward compatibility, otherwise if the class changes the serialize process would be aborted, the following code shows how to add the ID number:
       
 
        public class Tot_price {
The following code was inspired by the JAVA code in [http://lingpipe-blog.com/2009/08/10/serializing-immutable-singletons-serialization-proxy/ Serialization Proxy LingPipe]
        final int mPrice;
 
            final int mTax;
  public class Tot_price implements Serializable {
            public int price() { return mPrice; }
      ....
            public int tax() { return mTax; }
    static final long serialVersionUID = 200120012001L;
            public int total() {
      ....
                return price() + tax();
  }
            }
 
        }
Every time Java serializes an object, the ID number is computed through reflection, this causes to slow down the Serialization-De-serialization process, for this reason it is recommended to define in the code the ID number.
       
 
Immutable Class Proxy Serialized
==How is the Main Issue Solved?==
 
Since the Proxy Pattern is a '''private class''' then its inheritance is also private, if there is an immutable class, then its '''immutable implementation is also private''' and its details remains hidden after de-serialization the proxy pattern.
 
In this way the '''immutable properties are kept''' even in the other end side application and the variables cannot be modified.
 
==Reading Recommendations==
 
We recommend to read the following work [http://lingpipe-blog.com/2009/08/10/serializing-immutable-singletons-serialization-proxy/ Serializing Immutable and Singleton with a Serialization Proxy] written by '''LingPipe''', which covers also Singletons, it is very well explained and with JAVA examples to implement Serialization Proxy in Immutable classes.
 
It is also recommended to read Chapter 11 of the book [http://www.amazon.com/Effective-Java-2nd-Joshua-Bloch/dp/0321356683 Effective Java (2nd Edition)] by '''Joshua Bloch''', which explains in details in java the topic discussed here.
 
==Reference Books==
 
Effective Java (2nd Edition) [http://www.amazon.com/Effective-Java-2nd-Joshua-Bloch/dp/0321356683  by '''Joshua Bloch''']
 
Java™ for COBOL Programmers, Third Edition [http://my.safaribooksonline.com/9781598635655/ch10lev1sec4  by '''John C. Byrne''']
 
Java Examples in a Nutshell, 3rd Edition [http://my.safaribooksonline.com/0596006209/jenut3-CHP-10  by '''David Flanagan''']
 
Advanced JAVA Networking [http://my.safaribooksonline.com/0130844667/ch01lev1sec4  by '''Richard Steflik'''; '''Prashant Sridharan''']
 
Distributed Programming with Ruby [http://my.safaribooksonline.com/9780321669919 by '''Mark Bates''']
 
Ruby Cookbook [http://my.safaribooksonline.com/0596523696 by '''Lucas Carlson'''; '''Leonard Richardson''']
 
==External Links==
 
Forum on Serialization Proxy Pattern [http://stackoverflow.com/questions/702357/what-is-the-serialization-proxy-pattern stackoverflow.com] by '''Bob Carpenter''' Alias
 
Immutable Tutorial in JAVA[http://java.sun.com/docs/books/tutorial/essential/concurrency/immutable.html Java.sun.com]
 
Serialization Tutorial in JAVA  [http://java.sun.com/developer/technicalArticles/Programming/serialization/ java.sun.com#Serialization] and [http://java.sun.com/javase/6/docs/technotes/guides/serialization/ java.sun.com#Serialization_technotes]
 
Mutable and Immutable Objects in Ruby [http://rubylearning.com/satishtalim/mutable_and_immutable_objects.html Ruby Im & mutable Objects]
 
Overview on Serialization Wiki Page [http://en.wikipedia.org/wiki/Serialization Wiki/Serialization ]


        public class Tot_price implements Serializable {
Overview on Immutable Wiki Page [http://en.wikipedia.org/wiki/Immutable_class Wiki/Immutable Code]
       
            private final mPrice;
            private final mTax;
            public Tot_price(double price, double tax) { mPrice = price; mTax=tax; }
            ...
            private Object writeReplace() {
                return new SerializationProxy(this);
            }
       
            private static class SerializationProxy
                implements Serializable {
                int mPrice; int mTax;
                public SerializationProxy() { }
                public SerializationProxy(Tot_price cost) {
                    mPrice = cost.price();  mTax = cost.tax();
                }
                Object readResolve() {
                    return new Tot_price(mPrice,mTax);
                }
            }
        }
       
A random serial ID number is added whenever a class is Proxy Serialized by default. However, it is highly recommended to add it within the code in order to preserve forward compatibility, otherwise if the class changes the serialize process would be aborted, the Following code shows how to add the ID number:


        public class Tot_price implements Serializable {
Overview on Proxy Pattern Wiki Page [http://en.wikipedia.org/wiki/Proxy_pattern Wiki/Proxy Pattern]
         
            ...
         
            static final long serialVersionUID = -123456789L;
         
            ...
       
        }
       


Every time Java serializes an object, the ID number is computed through reflection, this causes to slow down the serializationàde-serialization process, for this reason it is recommended to define in the code the ID number.
Serialization Proxy LingPipe Blog [http://lingpipe-blog.com/2009/08/10/serializing-immutable-singletons-serialization-proxy/ lingpipe-blog.com] by '''Bob Carpenter''' Alias


==Conclusions==
==Appendix==
kuwekwbnxkwjnx


* The '''Class''' is a is a cohesive package that defines the abstract characteristics of a thing called object including its attributes and behaviors.


* '''Immutable''' classes are used to ensure the object state never gets changed.


* '''Java''' is a static object-oriented software platform, a technology developed by Sun Microsystems for machine-independent software.


http://stackoverflow.com/questions/702357/what-is-the-serialization-proxy-pattern
* The '''Method''' is the object's abilities, sometimes referred as their ''functions''
http://java.sun.com/javase/6/docs/technotes/guides/serialization/


http://my.safaribooksonline.com/9781598635655/ch10lev1sec4
* The '''Object''' consists of the state and behavior that was defined in the object class.


http://my.safaribooksonline.com/0596006209/jenut3-CHP-10
* '''Proxy Pattern''' is an object that interacts between source and sink applications within a network


http://my.safaribooksonline.com/0130844667/ch01lev1sec4
* '''Ruby''' is a dynamic, reflective, general-purpose object-oriented programming language.


http://en.wikipedia.org/wiki/Object_serialization
* '''Serialization''' is known as the process to convert a class into a sequence of bits and to store or sent them through the network


http://en.wikipedia.org/wiki/Immutable_class
* '''Singleton''' pattern is a design pattern that is used to restrict instantiation of a class to one object

Latest revision as of 04:51, 14 October 2009

Introduction and Objective

Immutable classes are used to ensure the object state never gets changed. On the other hand the concept of serialization is that applications can send and receive objects across the network; this is a step further than just keeping the object alive (persistence), which is the ability to call objects remotely, however private instances may be exposed by performing serialization.

Now the problem arises when serializing an immutable class and the immutability must be preserved between applications. There is a nice description of this problem in the stackoverflow.com Forum

The Serialization Proxy Pattern is capable to handle this kind of situations; henceforth the main objectives are to explain:

  • 1. It's idiomatic usage.
  • 2. How it is designed and gives details of its implementation.
  • 3. How the issue described above is handled.

When a Class is Immutable?

If a class state cannot be modified after being created then it is called immutable, on the contrary a mutable class can be modified after being created. There are also partially immutable classes, in which some of their attributes can be defined as immutable.

The key advantage is that they cannot be corrupted since the state cannot be changed.

To learn more about Immutable classes refer to the Java.sun.com Immutable Tutorial


The following is an example to illustrate immutable property:

 String  course_id=  "ECE517" ;
 course_id.toLowerCase();

In this case the course_id didn’t change to lower case, it remains as "ECE517" , although the output is “ece517" , instead the output is a new string that can be assigned to another variable, therefore and for the moment the values are still immutable, however the following code can change the value.

 course_id =  course_id.toLowerCase();

How to Make a Class Immutable?

Java Example

To make a class immutable we need to keep the class state safe by any means, in other words, assignments should never occur, the following code is an example of immutable class in JAVA

  final class Immutable_ece517Class 
  { 
     // To make the variables private use the term final
     final string nombre; 
     // Constructor where we can provide the constant value 
     public Immutable_ece517Class (string paramNombre) 
     { 
        nombre = paramNombre; 
     } 
     // Define the methods to return variable 
     public string getNombre
     { 
        return nombre; 
     } 
  }

See other examples in wiki/Immutable_class#Java

The trick here is that final before the variable restricts to write to private variables, the method after that is only to read the variable value without writing it.

Ruby Example

To implement immutable class in Ruby, the programmer must use the Struct.immutable instead of using Struct.new, the following is the code example implementation.

  def Struct.immutable(*args)  # Factory method for immutable classes
    Struct.new(*args).class_eval do # Define struct, then modify it
      undef []=                     # Un-define general mutation
      args.each do |sym|            # For each field of the struct
        mutator = :"#{sym.to_s}="   # Symbol for setter method
        remove_method mutator       # Un-define that method
      end
      self                          # Return the class
    end
  end

Visit mutable and immutable objects in Ruby for other examples

It is recommended to visit Wiki/Immutable Code, in there you can find immutable implementations in other languages.

What is Serialization?

It is known as the process from a source application to convert an object into a sequence of bits and to store or sent them through the network, in this way the same sequence can be retrieved by another end application that reconstructs or clones the original object in order to use it, this capability to store entire objects instead of simple parameters make possible to have high level distributed applications, without serialization the object would persist only while it is being executed (transient) and the application interaction would not be possible, e.g. remote procedure calls. Figure 1 Shows the Serialization/De-serialization process.


        Figure 1. The process of Serialization/De-serialization 


There is an option when an object is serialized, the state can also recorded in the byte stream, when it is retrieved its last state is also recovered, this feature allow the possibility to save the object state in memory and retrieve for its use later by the same application, the details to implement this feature are discussed in Proxy Serialization section, although there is also an application named as persistent that does the same, serialization can be also used as a persistent procedure to keep alive classes in local memory storage after being executed.

It is also possible to serialize complex data structures like applets and complete GUI (Graphical User Interface), but the scope of this wiki will be on class serialization only.

To have an insight on Serialization we recommend to visit wiki/Serialization

How to Implement Serialization of Classes?

Java Serialization

The next step would be in how to implement serialization of classes. In this case Java.io package offers the “writeObject()” to serialize and for un-serialize it uses “readObject( )” both are methods from ObjectOuputStream and ObjectOuputStream respectively, for an object to be serialized must have implemented the java.io.Serializable interface, the reason behind this is security, some private classes should not be exposed when de-serialize them, this is why a class must explicitly declare as serialize.

Below is the serialization code implementation in JAVA: taken from wiki/Object_serialization#java

  import java.io.*;
  /* The object to serialize. */
  class ObjectToSerialize implements Serializable {
      static private final long serialVersionUID = 42L;
      private String firstAttribute;
      private int secondAttribute;
      public ObjectToSerialize(String firstAttribute, int secondAttribute) {
          this.firstAttribute = firstAttribute;
          this.secondAttribute = secondAttribute;
      }
      @Override
      public String toString() {
          return firstAttribute + ", " + secondAttribute;
      }
  }
   public static void main(String[] args) {
       ObjectToSerialize original = new ObjectToSerialize("some text", 123);
       System.out.println(original);
       try {
           saveObject(original, "object.ser");
           ObjectToSerialize loaded = (ObjectToSerialize) loadObject("object.ser");
           System.out.println(loaded);
       } catch (Exception e) {
           e.printStackTrace();
       }
   }
  }

Ruby Serialization

Ruby uses the methods of dump and load from the Marshal module to perform serialization, however not all objects can be serialized, the exeptions are Bindings, Procedures and Singleton objects,

Below is the code implementation in Ruby, taken from wiki/Object_serialization#Ruby

  class Klass
    def initialize(str)
      @str = str
    end
    def sayHello
      @str
    end
  end
  
  o = Klass.new("hello\n")
  data = Marshal.dump(o)
  obj = Marshal.load(data)
  obj.sayHello   »  "hello\n"

The Main Issue when De-serialize an Immutable Class

The weakness in serialization is that the details of the hidden private instances may be exposed in the other end application which is not good, however in order to make remote call the end application must understand the de-serialized objects, this is why serialization formats have been developed to keep proprietary software, one clear example is that a password and login should never be serialized, it is too risky if this information is exposed in the form of a serialized variable class.


The main issue is that hidden private instances (immutable classes) can be exposed when de-serialize in the other end application and the idea is that they must remain safe and unchanged across applications. The solution proposed is the use of the Proxy Serialization Pattern.


You can find an alternate description of the problem or main issue written very well in a blog by "Bob Carpenter" Alias

What is a Proxy Pattern?

The Proxy Pattern, which is one of the most used design patterns, defines a proxy object that interacts between source and sink applications within a network, one common use of it is the ability to call a remote tasks and to share information trough a network.


To learn more on this topic please visit Wiki/Proxy Pattern


There are two most common types of proxies:

The first one is virtual proxy which creates the proxy object that interacts with the same application or other application within the same computer (stored in local memory), its purpose is to keep an object state alive after its execution so that it can be used later on.

The second one is remote proxy which creates the proxy object to be used in a different address space, commonly in a remote object on a distant host. It creates the illusion of interacting with the object or task directly, however there is a proxy between them that makes the interaction possible.

So, What is Proxy Serialization Pattern?

In general and summarized, the proxy serialization means that a class is serialized along with the method “writeReplace()” (Java), the result of this procedure is the so called “proxy serialization”, on the other end side the class is de-serialized along with the method “readResolve()” (Java) to reconstruct the class state (private properties).

The process to make a Proxy Serialization in more detail is listed below:


1. Before class serialization takes place, Java checks if the class contains the method “Object writeReplace()”.

2. If it does then the return value of “Object writeReplace()” is serialized together with the class (called Proxy Serialization), other wise only perform normal serialization on the class.

3. The proxy serialized value is used to keep the state of the original object to write (e.g. immutability), so that in the other end application the state can be recovered.

4. When de-serializing, Java checks if the class has the implementation of the method “Object readResolve()” if it does then it completes the de-serialization process and then the return value of the “readResolve()” is added to the de-serialization, which contains the state of the original object to write (e.g. immutability)


        Figure 2. The process of Proxy Serialization/De-serialization 

To Learn more refer to Chapter 11, item 76 of the book Effective Java (2nd Edition), Joshua Bloch Author


The key advantage of Proxy Serialization process is that proxy is implemented as a private static nested class, in figure 2 shows that its state is serialized (control of the read/write process) as well as the class itself, on the other end side the state is de-serialized (control of the read/write process) along with the class, in this way the class state is kept in the cloned class, this would keep the properties for example of an immutable implementation class.

Proxy Serialize Implementation in JAVA

The following code shows an example in Java; the first one is a typical immutable class, the second one is the serialization proxy implemented.

Typical Immutable Class

  public class Tot_price {
      final int mPrice;
      final int mTax;
      public int price() { return mPrice; }
      public int tax() { return mTax; }
      public int total() {
      return price() + tax();
  }

Typical Immutable with Class Proxy Serialization

The following code was inspired by the JAVA code in Serialization Proxy LingPipe

  public class Tot_price implements Serializable {
      private final mPrice;
      private final mTax;
      public Tot_price(double price, double tax) { mPrice = price; mTax=tax; }
      ...
      private Object writeReplace() {
          return new SerializationProxy(this);
      }
      
      private static class SerializationProxy
          implements Serializable {
          int mPrice; int mTax;
          public SerializationProxy() { }
          public SerializationProxy(Tot_price cost) {
              mPrice = cost.price();  mTax = cost.tax();
          }
          Object readResolve() {
              return new Tot_price(mPrice,mTax);
          }
      }
  }

Proxy Serialization Identification

A random serial ID number is added whenever a class is Proxy Serialized by default. However, it is highly recommended to add it within the code in order to preserve forward compatibility, otherwise if the class changes the serialize process would be aborted, the following code shows how to add the ID number:

The following code was inspired by the JAVA code in Serialization Proxy LingPipe

  public class Tot_price implements Serializable {
     ....
   static final long serialVersionUID = 200120012001L;
     ....
  }

Every time Java serializes an object, the ID number is computed through reflection, this causes to slow down the Serialization-De-serialization process, for this reason it is recommended to define in the code the ID number.

How is the Main Issue Solved?

Since the Proxy Pattern is a private class then its inheritance is also private, if there is an immutable class, then its immutable implementation is also private and its details remains hidden after de-serialization the proxy pattern.

In this way the immutable properties are kept even in the other end side application and the variables cannot be modified.

Reading Recommendations

We recommend to read the following work Serializing Immutable and Singleton with a Serialization Proxy written by LingPipe, which covers also Singletons, it is very well explained and with JAVA examples to implement Serialization Proxy in Immutable classes.

It is also recommended to read Chapter 11 of the book Effective Java (2nd Edition) by Joshua Bloch, which explains in details in java the topic discussed here.

Reference Books

Effective Java (2nd Edition) by Joshua Bloch

Java™ for COBOL Programmers, Third Edition by John C. Byrne

Java Examples in a Nutshell, 3rd Edition by David Flanagan

Advanced JAVA Networking by Richard Steflik; Prashant Sridharan

Distributed Programming with Ruby by Mark Bates

Ruby Cookbook by Lucas Carlson; Leonard Richardson

External Links

Forum on Serialization Proxy Pattern stackoverflow.com by Bob Carpenter Alias

Immutable Tutorial in JAVAJava.sun.com

Serialization Tutorial in JAVA java.sun.com#Serialization and java.sun.com#Serialization_technotes

Mutable and Immutable Objects in Ruby Ruby Im & mutable Objects

Overview on Serialization Wiki Page Wiki/Serialization

Overview on Immutable Wiki Page Wiki/Immutable Code

Overview on Proxy Pattern Wiki Page Wiki/Proxy Pattern

Serialization Proxy LingPipe Blog lingpipe-blog.com by Bob Carpenter Alias

Appendix

  • The Class is a is a cohesive package that defines the abstract characteristics of a thing called object including its attributes and behaviors.
  • Immutable classes are used to ensure the object state never gets changed.
  • Java is a static object-oriented software platform, a technology developed by Sun Microsystems for machine-independent software.
  • The Method is the object's abilities, sometimes referred as their functions
  • The Object consists of the state and behavior that was defined in the object class.
  • Proxy Pattern is an object that interacts between source and sink applications within a network
  • Ruby is a dynamic, reflective, general-purpose object-oriented programming language.
  • Serialization is known as the process to convert a class into a sequence of bits and to store or sent them through the network
  • Singleton pattern is a design pattern that is used to restrict instantiation of a class to one object