Tuesday, December 25, 2012

Collections : Keys in a Map 3 And Final

Finally this post is about the class which is immutable and can be a valid key in a Map. We would correct both the approaches we have discussed earlier. The first where we had a setter method. And the second where the class could be manipulated by an inheritor class.

    /**
     *
     *
     * @author Sanjay
     *
     */
    static interface Key {
        /**
         *
         *
         * @return
         */
        public String getKey();
    }
 

First we define the interface using which we will put the keys in the Map. As the reader can see the interface needs a single method to be implemented for its children. The getKey() method which returns a property (essentially a state holding property) of type String.

Next we have two classes implementing this interface using their different approaches.

The first implementer.

 

    /**
     *
     * Valid because the setter property has been eliminated and the state holding property is private making the class immutable.
     *
     * @author Sanjay
     *
     */
    static class ValidKey1 implements Key {
        private String key;

        /**
         *
         *
         * @return
         */
        public String getKey() {
            return key;
        }

        /**
         *
         *
         * @param key
         */
        public ValidKey1(String key) {
            super();
            this.key = key;
        }
      
        /**
         *
         * We re-use the String equals
         *
         */
        @Override
        public boolean equals(Object obj) {
            if(obj instanceof Key) {
                if(((Key)obj).getKey().equals(this.key)) return true;
                else return false;
            }
            else return false;
        }
      
        /**
         *
         * We re-use the Object hashCode and the String code hashCode if the key is not null.
         *
         */
        @Override
        public int hashCode() {
            if(key!=null) return this.key.hashCode(); // we simply return String's hash code
            return super.hashCode(); // if key is null then we return the Object's hash code value.
        }
      
        /**
         *
         *
         */
        public String toString() {
            StringBuffer buffer = new StringBuffer("");
            buffer.append(this.key);
            return buffer.toString();
        }
      
    }




The second implementer.

 

/**
     *
     * Valid because although the class can be extended and its inheritors can access the state changing property it can be overridden as it is a final property and is set through the Constructor.
     *
     * @author Sanjay
     *
     */
    static class ValidKey2 implements Key {
        protected final String key;

        /**
         *
         *
         * @return
         */
        public String getKey() {
            return key;
        }

        /**
         *
         *
         * @param key
         */
        public ValidKey2(String key) {
            this.key = key;
        }
      
        /**
         *
         * We re-use the String equals
         *
         */
        @Override
        public boolean equals(Object obj) {
            if(obj instanceof Key) {
                if(((Key)obj).getKey().equals(this.key)) return true;
                else return false;
            }
            else return false;
        }
       
        /**
         *
         * We re-use the Object hashCode and the String code hashCode if the key is not null.
         *
         */
        @Override
        public int hashCode() {
            if(key!=null) return this.key.hashCode(); // we simply return String's hash code
            return super.hashCode(); // if key is null then we return the Object's hash code value.
        }
       
        /**
         *
         *
         */
        public String toString() {
            StringBuffer buffer = new StringBuffer("");
            buffer.append(this.key);
            return buffer.toString();
        }
       
    }




The second Implementer can be extended but the state holding property cannot be overriden.

 

/**
     *
     * @author Sanjay
     *
     */
    static class ValidKey3 extends ValidKey2 {
      
        /**
         *
         *
         * @param key
         */
        public ValidKey3(String key) {
            // TODO Auto-generated constructor stub
            super(key);
        }
      
        public void setKey(String key) {
//            super.key = key; // this DOES NOT COMPILE
        }
    }





The client code calling the above is below.

 

package org.home.project21.study.designPatterns;

import java.util.HashMap;
import java.util.Map;

/**
 *
 * Collections : Keys in a Map 3 And Final
 *
 *
 * @author Sanjay
 *
 */
public class CollectionsTest3 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Map myMap = new HashMap();
        Key iKey = new ValidKey1("ValidKey");
        Key iKeyRef = new ValidKey3("ValidKey"); // creating a new key with the same value
      
        myMap.put(iKey, "This is Value");
      
        iKey = null; // we remove the link from the first reference to the Object
        System.out.println(" myMap has  " + myMap.get(iKeyRef) + " against this key " + iKeyRef.toString());// this will print the correct value
      
         // iKeyRef.setKey("InvalidKey2");                       this DOES NOT COMPILE
      
        System.out.println(" myMap has  " + myMap.get(iKeyRef) + " against this key " + iKeyRef.toString());// this will print the correct value

      
    }



The final output is below. as one can see here we are able to both put and retrieve the values in the Map.

 

myMap has This is Value against this key ValidKey 
myMap has This is Value against this key ValidKey

Collections : Keys In a Map 2

Next I tried to write a key class which would not have a setter method. But what if the state of the property is changed by the inheritors of this class? For that we need to make the property final. Another point of view would be to make the entire class final. But that would make any enhancements to the parent class impossible. Given that there might be key features which are not immediately visible at the time of parent class creation, this is a usable idea.

Let us see what happens when we leave the state holding property of the parent Class to the manipulation of the future inheritor classes.
 
        /**
         *
         *
         * @param key
         */
        public InvalidKey2(String key) {
            super();
            this.key = key;
        }
      
        /**
         *
         * We re-use the String equals
         *
         */
        @Override
        public boolean equals(Object obj) {
            if(obj instanceof InvalidKey2) {
                if(((InvalidKey2)obj).getKey().equals(this.key)) return true;
                else return false;
            }
            else return false;
        }
       
        /**
         *
         * We re-use the Object hashCode and the String code hashCode if the key is not null.
         *
         */
        @Override
        public int hashCode() {
            if(key!=null) return this.key.hashCode(); // we simply return String's hash code
            return super.hashCode(); // if key is null then we return the Object's hash code value.
        }
       
        /**
         *
         *
         */
        public String toString() {
            StringBuffer buffer = new StringBuffer("");
            buffer.append(this.key);
            return buffer.toString();
        }
       
    }


   In the above code the state changing property is protected which means any inheritor class can manipulate the property. And although spoiler setter method is eliminated we will see how access specifier makes the class quite unsuitable for a Key in a Map.


 

    /**
     *
     * This is invalid because the state-change property has been made as protected and the class is extended
     *
     * @author Sanjay
     *
     */
    static class InvalidKey3 extends InvalidKey2 {
      
        /**
         *
         *
         * @param key
         */
        public InvalidKey3(String key) {
            super(key);
        }

        /**
         * 

         * The Spolier Method
         * @param key
         */
        public void setKey(String key) {
            // TODO Auto-generated method stub
            super.key = key;
        }
    }



The Original parent class is now extended by the above class and a setter method has been added and thereby nullifying the objective. If we use the Parent Class then we don't run into a problem. But any client class which uses an extended version like the one above may run into one. Please check the code below.




 
package org.home.project21.study.designPatterns;

import java.util.HashMap;
import java.util.Map;


/**
 *
 *
 * Collections : Keys in a Map 2
 *
 *
 */
public class CollectionsTest2 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Map myMap = new HashMap();
        InvalidKey2 iKey = new InvalidKey2("InvalidKey1");
        InvalidKey2 iKeyRef = new InvalidKey3("InvalidKey1"); // creating a new key with the same value
        myMap.put(iKey, "This is Value");
        iKey = null; // we remove the link from the first reference to the Object
        System.out.println(" myMap has  " + myMap.get(iKeyRef) + " against this key " + iKeyRef.toString() + " myMap " + myMap);// this will print the correct value
        ((InvalidKey3)iKeyRef).setKey("InvalidKey2");
        System.out.println(" myMap has  " + myMap.get(iKeyRef) + " against this key " + iKeyRef.toString() + " myMap " + myMap);// this will print the correct value

    }



Here we create two keys one with the parent class and the other with the child class. With the parent class object we insert the value in the map. And nullify it. On the first attempt the child class is able to retrieve it however on the second attempt the key fails the equality test as the state holding property has been reset by the setter method in the child class.

 Below is the Output

 

myMap has This is Value against this key InvalidKey1 myMap {InvalidKey1=This is Value} myMap has null against this key InvalidKey2 myMap {InvalidKey1=This is Value}

Collections : Keys in a Map 1

Some time ago I was needed to write my own custom classes for keys in Maps. That brought me to the concept of immutable classes which are needed to be valid keys in a Map. 

Let us look at the code below. It is an inner class which has a state-holding property of type String which is set through the Constructor. In addition to that it overrides the methods with which the HashMap or any other implementation of Map would 'bucket' it and check the equality with a future retrieval. 
 
    /**
     *
     * Invalid because this has a mutable property key of type String. It is mutable as it has a setter method.
     *
     * @author Sanjay
     *
     */
    static class InvalidKey {
        private String key;

        /**
         *
         *
         * @return
         */
        public String getKey() {
            return key;
        }

        /**
         * The spoiler method
         *
         * @param key
         */
        public void setKey(String key) {
            this.key = key;
        }


        /**
         *
         *
         * @param key
         */
        public InvalidKey(String key) {
            super();
            this.key = key;
        }
       
        /**
         *
         * We re-use the String equals
         *
         */
        @Override
        public boolean equals(Object obj) {
            if(obj instanceof InvalidKey) {
                if(((InvalidKey)obj).getKey().equals(this.key)) return true;
                else return false;
            }
            else return false;
        }
       
        /**
         *
         * We re-use the Object hashCode and the String code hashCode if the key is not null.
         *
         */
        @Override
        public int hashCode() {
            if(key!=null) return this.key.hashCode(); // we simply return String's hash code
            return super.hashCode(); // if key is null then we return the Object's hash code value.
        }
       
        /**
         *
         *
         */
        public String toString() {
            StringBuffer buffer = new StringBuffer("");
            buffer.append(this.key);
            return buffer.toString();
        }
       
    }



The problem with the above class is that the setter method with the javadoc comment Spolier method can be used to reset the Key after the Map has been modified with this key. An example of the use will elucidate the problem.
package org.home.project21.study.designPatterns;

import java.util.HashMap;
import java.util.Map;

/**
 *
 *
 * Collections : Keys in a Map 1
 *
 *
 *
 * @author Sanjay
 *
 */
public class CollectionsTest1 {


    /**
     * @param args
     */
public static void main(String[] args) {
        // TODO Auto-generated method stub
        Map myMap = new HashMap();
        InvalidKey iKey = new InvalidKey("InvalidKey1");
        InvalidKey iKeyRef = new InvalidKey("InvalidKey1"); // creating a new key with the same value
        myMap.put(iKey, "This is Value");
        iKey = null; // we remove the link from the first reference to the Object
        System.out.println(" myMap has  " + myMap.get(iKeyRef) + " against this key " + iKeyRef.toString());// this will print the correct value
        iKeyRef.setKey("InvalidKey2");
        System.out.println(" myMap has  " + myMap.get(iKeyRef) + " against this key " + iKeyRef.toString());// this will print the correct value
}


The following is the output of the Program.
myMap has This is Value against this key InvalidKey1 
myMap has null against this key InvalidKey2 As can be seen from the output the key is unable to retrieve the Value from the Map as the Object is mutable and has it's state changed. So the equality test fails and hence a null is returned.

Thursday, December 13, 2012

Design Patterns : Abstract Factory Pattern 3

Finally we are now ready to see the Solution of our problem. The Abstract factory can return the exact type of Computer by calling the required factory of the type required. We need to call the implementations of the Server, WorkStation, Notebook and Tablet as factories since the Client always wants a Computer and the Abstract Factory is unaware of the Components which make up the Computer.

First ComputerAbstractFactory.


package com.company.self.study.core.java;

/**
 *
 * Abstract Factory Pattern Example
 *
 * @author administrator
 *
 */
  public class ComputerAbstractFactory {

  private static ComputerAbstractFactory instance = new  ComputerAbstractFactory();

/**
 *
 *
 * @return
 */
  public static ComputerAbstractFactory getInstance() {
   return instance;
  }

/**
 *
 *
 *
 * @param type
 * @return
 * @throws Exception
 */
@SuppressWarnings("unchecked")
public Computer getComputer(String type) {
  Computer computer = null;
  Component processorCore = null;
  Component hardDisk = null;
  Component memory = null;
  if ("Server".equals(type)) {
     computer = new Server();// Servers are always default
  }
  else if ("WorkStation".equals(type)) {
    computer = new WorkStation();// we need a default workstation.
  }
  else if ("NoteBook".equals(type)) {
    computer = new NoteBook();
  }
  else if ("Tablet".equals(type)) {
    computer = new Tablet();

  }
  else {
    System.out.println(" this " + type + " is not current available ");
    throw new UnsupportedOperationException(" this " + type + " is not current     available ");
    }
    return computer;
  }
}


Next ComputerAbstractFactoryTester.


package com.company.self.study.core.java;

/**
*
* Abstract Factory Pattern Example
*
* @author administrator
*
*/
public class ComputerAbstractFactoryTester {

/**
*
* Client Class is unaware of the names of the Class Implementations or even of the component classes that are used to build.
* It is a coincidence that the type and the implementations are the same.
*
* @param args
*/ public static void main(String[] args) {
System.out.println(" ComputerAbstractFactoryTester start "); Computer c1 = ComputerAbstractFactory.getInstance().getComputer("Server");
Computer c2 = ComputerAbstractFactory.getInstance().getComputer("WorkStation");
Computer c3 = ComputerAbstractFactory.getInstance().getComputer("NoteBook");
Computer c4 = ComputerAbstractFactory.getInstance().getComputer("Tablet");
System.out.println(" c1 " + c1);
System.out.println(" c2 " + c2);
System.out.println(" c3 " + c3);
System.out.println(" c4 " + c4);
System.out.println(" ComputerAbstractFactoryTester end ");
}

}


Finally we are ready to run the tester through a command script.
 The Command Script

"C:\Program Files\Java\jdk1.6.0_26\bin"\javac -classpath bin -d bin src\com\company\self\study\core\java\ClassTemplate.java

"C:\Program Files\Java\jdk1.6.0_26\bin"\javac -classpath bin -d bin src\com\company\self\study\core\java\Component.java

"C:\Program Files\Java\jdk1.6.0_26\bin"\javac -classpath bin -d bin src\com\company\self\study\core\java\Computer.java

"C:\Program Files\Java\jdk1.6.0_26\bin"\javac -classpath bin -d bin src\com\company\self\study\core\java\ProcessorCore.java

"C:\Program Files\Java\jdk1.6.0_26\bin"\javac -classpath bin -d bin src\com\company\self\study\core\java\HardDisk.java

"C:\Program Files\Java\jdk1.6.0_26\bin"\javac -classpath bin -d bin src\com\company\self\study\core\java\Memory.java

"C:\Program Files\Java\jdk1.6.0_26\bin"\javac -classpath bin -d bin src\com\company\self\study\core\java\Server.java

"C:\Program Files\Java\jdk1.6.0_26\bin"\javac -classpath bin -d bin src\com\company\self\study\core\java\WorkStation.java

"C:\Program Files\Java\jdk1.6.0_26\bin"\javac -classpath bin -d bin src\com\company\self\study\core\java\NoteBook.java

"C:\Program Files\Java\jdk1.6.0_26\bin"\javac -classpath bin -d bin src\com\company\self\study\core\java\Tablet.java

"C:\Program Files\Java\jdk1.6.0_26\bin"\javac -classpath bin -d bin src\com\company\self\study\core\java\ComputerAbstractFactory.java

"C:\Program Files\Java\jdk1.6.0_26\bin"\javac -classpath bin -d bin src\com\company\self\study\core\java\ComputerAbstractFactoryTester.java

java -classpath bin com.company.self.study.core.java.ComputerAbstractFactoryTester > Output_ComputerAbstractFactoryTester.txt



At last the output file

ComputerAbstractFactoryTester start
c1 server with DecaCore 40 GB RAM 100 TB physical disk
c2 workstation with QuadCore 8 GB RAM 1 TB physical disk
c3 notebook with QuadCore 4 GB RAM 100 GB physical disk
c4 tablet with DualCore 2 GB RAM 40 GB physical disk
ComputerAbstractFactoryTester end


Design Patterns : Abstract Factory Pattern 2

The reader might have already observed that we need a component interface to define the minimum three components of the Computer factories. The below listing provides the Component interface

package com.company.self.study.core.java;

/**
*
* Abstract Factory Pattern Example
*
* @author administrator
*
*/
public interface Component {

}


Next we start on the designing the components which are being used by the independent factories of the Computer to churn the concrete implementations

 The Processor Core first

package com.company.self.study.core.java;

/**
*
*
* Abstract Factory Pattern Example
*
* @author administrator
*
*/
public class ProcessorCore implements Component {

private String core;



public ProcessorCore(String core) {
super();
this.core = core;
}

public String getCore() {
return core;
}
public void setCore(String core) {
this.core = core;
}

public String toString() {
return core;
}
}


 Next Memory


package com.company.self.study.core.java;

/**
*
* Abstract Factory Pattern Example
*
*
* @author administrator
*
*/
public class Memory implements Component {

private String size;

public Memory(String size) {
super();
this.size = size;
}

public String getSize() {
return size;
}

public void setSize(String size) {
this.size = size;
}


public String toString() {
return size;
}
}


 Finally HardDisk

package com.company.self.study.core.java;

/**
*
* Abstract Factory Pattern Example
*
*
*
* @author administrator
*
*/
public class HardDisk implements Component {

private String volume;



public HardDisk(String volume) {
super();
this.volume = volume;
}

public String getVolume() {
return volume;
}

public void setVolume(String volume) {
this.volume = volume;
}

public String toString() {
return volume;
}
}


 On next post we would terminate the discussion by listing the actual Abstract Factory and the Tester. Of course with the Runner and the Output listed too.

Wednesday, December 12, 2012

Design Patterns : Abstract Factory Pattern 1


Some years ago in an interview for an entry-to-middle level job,
I was asked by the interviewer about the Abstract Factory.
The interviewer then intentionally tried to confuse me by asking what
is a Factory and what are the differences between the Two.
I provided him the following example.


Suppose say you are the CTO of a new company and want
the computers in your new organization to be set up immediately.
Now even assuming that the CTO is immensely tech savvy you can not expect
him to buy a bulk amount of systems or build them under supervision
as per the requirement,


The first would not serve the minimum fitness-for-purpose, for the
simple reason that the Servers which would host the website of the company
the workstation on which the employees do their daily work
the laptops on which the Sales Executive provides the Client Presentations
all need to be different.

The second would serve the minimum fitness-for-purpose, but would
not serve the cost-effectiveness. Also the man days necessary to supervise would
outweigh the benefits. So the solution must meet the fitness-for-purpose
within the budget.


If the following listing encapsulates the Computer Object


package com.company.self.study.core.java;

/**
 *
 * Abstract Factory Pattern Example
 *
 * @author administrator
 *
 */
public interface Computer {

   /**
    *
    *
    *
    * @return
    *
    public Component getProcessorCore();

   /**
    *
    *
    *
    * @return
    *
    public Component getMemory();


   /**
    *
    *
    *
    * @return
    *
    public Component getHardDisk();

}


Then we can define the concrete implementation of the different kinds
of Computers which needed to be ordered based on specification, based on
the below listed Specifications.


Server


package com.company.self.study.core.java;

    /**
    *
    * Abstract Factory Pattern Example
    *
    *
    *
    * @author administrator
    *
    *
public class Server implements Computer {

    private Component hardDisk;
    private Component memory;
    private Component processorCore;

    /**
    *
    *
    *
    */
    public Server() {
    processorCore = new ProcessorCore(" DecaCore ");
    hardDisk = new HardDisk(" 100 TB ");
    memory = new Memory(" 40 GB ");
    }

    /**
    *
    *
    *
    * @param hardDisk
    * @param memory
    * @param processorCore
    */
    public Server(Component hardDisk, Component memory, Component processorCore) {
    this();
    this.hardDisk = hardDisk;
    this.memory = memory;
    this.processorCore = processorCore;
    }


    @Override
    public Component getHardDisk() {
    // TODO Auto-generated method stub
    return hardDisk;
    }

    @Override
    public Component getMemory() {
    // TODO Auto-generated method stub
    return memory;
    }

    @Override
    public Component getProcessorCore() {
    // TODO Auto-generated method stub
    return processorCore;
    }

    /**
    *
    *
    *
    */
   
@Override
    public String toString() {
    return " server with " + processorCore + " " + memory + " RAM " + hardDisk +   " physical disk ";
    }
}


WorkStation


package com.company.self.study.core.java;

/**
*
* Abstract Factory Pattern Example
*
*
* @author administrator
*
*/
public class WorkStation implements Computer {

private Component hardDisk;
private Component memory;
private Component processorCore;


/**
*
*
*
*/
public WorkStation() {
super();
processorCore = new ProcessorCore(" QuadCore ");
hardDisk = new HardDisk(" 1 TB ");
memory = new Memory(" 8 GB ");
}
/**
*
*
*
* @param hardDisk
* @param memory
* @param processorCore
*/
public WorkStation(Component hardDisk, Component memory, Component processorCore) {
super();
this.hardDisk = hardDisk;
this.memory = memory;
this.processorCore = processorCore;
}

@Override
public Component getHardDisk() {
// TODO Auto-generated method stub
return hardDisk;
}

@Override
public Component getMemory() {
// TODO Auto-generated method stub
return memory;
}

@Override
public Component getProcessorCore() {
// TODO Auto-generated method stub
return processorCore;
}
/**
*
*
*
*/
@Override
public String toString() {
return " workstation with " + processorCore + " " + memory + " RAM " + hardDisk + " physical disk ";
}

}


NoteBook


package com.company.self.study.core.java;

/**
*
* Abstract Factory Pattern Example
*
*
* @author administrator
*
*/
public class NoteBook implements Computer {

private Component hardDisk;
private Component memory;
private Component processorCore;


/**
*
*
*
*/
public NoteBook() {
super();
processorCore = new ProcessorCore(" QuadCore ");
hardDisk = new HardDisk(" 100 GB ");
memory = new Memory(" 4 GB ");
}
/**
*
*
*
* @param hardDisk
* @param memory
* @param processorCore
*/
public NoteBook(Component hardDisk, Component memory, Component processorCore) {
super();
this.hardDisk = hardDisk;
this.memory = memory;
this.processorCore = processorCore;
}

@Override
public Component getHardDisk() {
// TODO Auto-generated method stub
return hardDisk;
}

@Override
public Component getMemory() {
// TODO Auto-generated method stub
return memory;
}

@Override
public Component getProcessorCore() {
// TODO Auto-generated method stub
return processorCore;
}

/**
*
*
*
*/
@Override
public String toString() {
return " notebook with " + processorCore + " " + memory + " RAM " + hardDisk + " physical disk ";
}

}


Tablet


package com.company.self.study.core.java;


/**
*
* Abstract Factory Pattern Example
*
*
*
* @author administrator
*
*/
public class Tablet implements Computer {

private Component hardDisk;
private Component memory;
private Component processorCore;


/**
*
*
*
* @param hardDisk
* @param memory
* @param processorCore
*/
public Tablet() {
super();
processorCore = new ProcessorCore(" DualCore ");
hardDisk = new HardDisk(" 40 GB ");
memory = new Memory(" 2 GB ");
}



/**
*
*
*
* @param hardDisk
* @param memory
* @param processorCore
*/
public Tablet(Component hardDisk, Component memory, Component processorCore) { super();
this.hardDisk = hardDisk;
this.memory = memory;
this.processorCore = processorCore;
}

@Override
public Component getHardDisk() {
// TODO Auto-generated method stub
return hardDisk;
}

@Override
public Component getMemory() {
// TODO Auto-generated method stub
return memory;
}

@Override
public Component getProcessorCore() {
// TODO Auto-generated method stub
return processorCore;
}

/**
*
*
*
*/
@Override
public String toString() {
return " tablet with " + processorCore + " " + memory + " RAM " + hardDisk + " physical disk ";
}


}


Tuesday, December 11, 2012

Design Patterns : Factory Pattern 2


Finally we come to the main class of our little POC
We now focus our attention to the factory class ChildFactory
ChildFactory which essentially instantiates a child whether
it is a Boy or a Girl


package com.company.self.study.core.java;

/**
*
* Factory Pattern Example
*
* @author administrator
*
*/
public class ChildFactory {

   private static ChildFactory instance = new ChildFactory();

/**
*
*
*
*
* @return
*/
   public static ChildFactory getInstance() {
      return instance;
   }

/**
*
*
*
* @param age
* @param isMale
* @return
*/
   public Child getChild(int age, boolean isMale) {
      Child child = null;
      if(isMale) {
         child = new Boy(age);
      }
      else {
      child = new Girl(age);
      }
      return child;
   }
}


As we can see this class is a Singleton and
has a static object creator. Apart from that the
only other method getChild(age, isMale) the class has
actually does the bulk of the work. It returns the Boy class
if the isMale argument is true. Else it would return the Girl class


Finally we have the ChildFactoryTester class which
actually tests the application. The below listing includes it.



package com.
company.self.study.core.java;


/**
*
* Factory Pattern Example
*
*
* @author administrator
*
*/
@ClassTemplate(date="12/05/2012")
public class ChildFactoryTester {

/**
* @param args
*/
   public static void main(String[] args) {
// TODO Auto-generated method stub
      System.out.println(" ChildFactoryTester start ");
      Child firstIssue = ChildFactory.getInstance().getChild(5, true);
      Child secondIssue = ChildFactory.getInstance().getChild(3, false);
      System.out.println(" firstIssue " + firstIssue + " secondIssue " + secondIssue);
      System.out.println(" ChildFactoryTester end ");
}

}


The below listing is for the Class Annotation which
encapsulates the date of the program and the name of the programmer.




package com.
company.self.study.core.java;

public @interface ClassTemplate {
   String author() default "[Sanjay Ghosh]";
   String date() default "[1/1/2001]";
}



Now we are ready to run the Tester through a command script and
the pipe the output to an Output File. Below are the listings for the script
and the final output.


Command Script


"C:\Program Files\Java\jdk1.6.0_26\bin"\javac -classpath bin -d bin src\com\company\self\study\core\java\ClassTemplate.java

"C:\Program Files\Java\jdk1.6.0_26\bin"\javac -classpath bin -d bin src\com\
company\self\study\core\java\Father.java

"C:\Program Files\Java\jdk1.6.0_26\bin"\javac -classpath bin -d bin src\com\
company\self\study\core\java\Mother.java

"C:\Program Files\Java\jdk1.6.0_26\bin"\javac -classpath bin -d bin src\com\
company\self\study\core\java\Child.java

"C:\Program Files\Java\jdk1.6.0_26\bin"\javac -classpath bin -d bin src\com\
company\self\study\core\java\Boy.java

"C:\Program Files\Java\jdk1.6.0_26\bin"\javac -classpath bin -d bin src\com\
company\self\study\core\java\Girl.java

"C:\Program Files\Java\jdk1.6.0_26\bin"\javac -classpath bin -d bin src\com\
company\self\study\core\java\ChildFactory.java

"C:\Program Files\Java\jdk1.6.0_26\bin"\javac -classpath bin -d bin src\com\
company\self\study\core\java\ChildFactoryTester.java

java -classpath bin com.
company.self.study.core.java.ChildFactoryTester > Output_ChildFactoryTester.txt



Output File


ChildFactoryTester start
firstIssue Boy of 5 yrs secondIssue Girl of 3 yrs
ChildFactoryTester end


Design Patterns : Factory Pattern 1


Factory Pattern is another Design Pattern that has long interested me in
my work. Basically we use factory pattern when we want to leave the actual
invocation of a concrete implementation to a decider class called as the
factory class. The client class need not know anything about the
product class but would call it's the exposed API to do the work. The exposed
might be an interface which the factory would always honour.

Let's say we have an interface Child listed below which has a single
API which provides the age. The age needs to be below a certain limit which
would be decided by the Client code. But the Client doesn't want to know
the gender of the Child and nor it's parentage. All that is the headache of the
factory class which would provide the Child



package com.company.self.study.core.java;

/**
*
* Factory Pattern Example
*
*
* @author administrator
*
*/
public interface Child extends Father, Mother {

public int getAge();
}


The interface Child extends both Father and
Mother but would have an unique gender.


The Father and the Mother classes are listed below

package com.company.self.study.core.java;

/**
*
* Factory Pattern Example
*
* @author administrator
*
*/
public interface Father {

public boolean isMale();
}


In the same way the Mother class is also written

package com.company.self.study.core.java;

/**
*
* Factory Pattern Example
*
* @author administrator
*
*/
public interface Mother {

public boolean isFemale();
}


Next we implement two concrete class which have implemented the Child
class. Currently we are recognizing only two kinds of children. Male or female.
To support that we have two implementations Boy and
Girl
The below listing provides the concrete implementations.
package com.company.self.study.core.java;

/**
*
* Factory Pattern Example
*
*
* @author administrator
*
*/
@ClassTemplate(date="12/05/2012")
public class Boy implements Child {

private int age;


/**
*
*
*
* @param age
*/
public Boy(int age) {
this.age = age;
}


/**
*
*
*
*/
@Override
public int getAge() {
// TODO Auto-generated method stub
return 0;
}



/**
*
*
*
*/
@Override
public boolean isMale() {
// TODO Auto-generated method stub
return true;
}

/**
*
*
*
*/
@Override
public boolean isFemale() {
// TODO Auto-generated method stub
return false;
}

/**
*
*
*/
@Override
public String toString() {
return " Boy of " + age + " yrs ";
}
}



The next is the Girl class implementation.


package com.company.self.study.core.java;


/**
*
* Factory Pattern Example
*
*
* @author administrator
*
*/
@ClassTemplate(date="12/05/2012")
public class Girl implements Child {

private int age;


/**
*
*
*
* @param age
*/

public Girl(int age) {
this.age = age;
}


/**
*
*
*
*
*
*/
@Override
public int getAge() {
// TODO Auto-generated method stub
return 0;
}

/**
*
*
*
*
*/
@Override
public boolean isMale() {
// TODO Auto-generated method stub
return false;
}

/**
*
*
*
*
*
*/
@Override
public boolean isFemale() {
// TODO Auto-generated method stub
return true;
}


/**
*
*
*/
@Override
public String toString() {
return " Girl of " + age + " yrs ";
}
}


Sunday, December 9, 2012

Design Patterns : Observer Pattern 2

The LoginObservable which has a observers attribute and a currentUsers_ attribute. The former is a list of all the Observers which are registered with the system and the latter is a Map of all the Users currently active on the System.

We also have two flags changed which is essentially indicator of whether the Observable system has changed.
Let us go through the Use case methods first
/**
*
*
*
*/
public IUser login(String userName, char [] password) {
// check pss
changed = true;
IUser user = new User(userName);
if(currentUsers_ == null) {
currentUsers_ = new HashMap();
}
currentUsers_.put(userName, user);
notifyObservers(user);// notify all Observers of this user
return user;
}

Now this method logs the User in. It takes a user name and password creates a
IUser object and then updates both the current User and then the changes
inidicator. The reader can take note of the notifyObservers method
which will be discussed in details later
Somewhat on similar lines the next usecase method is written
/**
*
*
*
*
*/
public IUser logout(String userName, char [] password) {
// check pss
changed = true;
IUser user = null;
if(currentUsers_ != null) {
if(currentUsers_.containsKey(userName)) {
//double check pss
user = currentUsers_.get(userName);
currentUsers_.put(userName, null);
}
}
notifyObservers(user);// notify all Observers of this user
return user;
}


the changed indicator is once again changed the current Users is updated and once
again the notifyObservers method is called.

Next we check on the same method /**
*
*/
@Override
public void notifyObservers(Object arg) {
// TODO Auto-generated method stub
Observer [] observersArray = new Observer[observers.size()];
int count = 0;
for(Observer observer : observers) {
observersArray[count++] = observer;
}

if(this.hasChanged()) {
for(Observer observer : observersArray) {
observer.update(this, arg);
}
}
clearChanged();
observersArray = null;
}
It simply creates an Observer array out of the Observer list and checks
if the Observable has changed .
Then for every element of the array the update method is called.


Finally the clearChanged is called to reset the status to
not changed and the array is freed.

Last we need a Test class and a test script to see the program in action
package org.home.project21.study.designPatterns;

import java.util.Observable;
import java.util.Observer;

public class LoginTester {

/**
* @param args
*/
public static void main(String[] args) {
ILogUser logUser = new LoginObservable(); // want to check who logs in and why
Observer observer = new LoginObserver(); // create an Observer
((Observable)logUser).addObserver(observer); // add it
logUser.login("Alan Stair", "123".toCharArray()); // log in an Observer
logUser.logout("Alan Stair", "123".toCharArray());// log out an Observer
}


}
And the script

javac -sourcepath src -classpath bin -d bin C:\work\workspace\Project21\src\org\home\project21\study\designPatterns\IUser.java
javac -sourcepath src -classpath bin -d bin C:\work\workspace\Project21\src\org\home\project21\study\designPatterns\ILogUser.java
javac -sourcepath src -classpath bin -d bin C:\work\workspace\Project21\src\org\home\project21\study\designPatterns\User.java
javac -sourcepath src -classpath bin -d bin C:\work\workspace\Project21\src\org\home\project21\study\designPatterns\LoginObserver.java
javac -sourcepath src -classpath bin -d bin C:\work\workspace\Project21\src\org\home\project21\study\designPatterns\LoginObservable.java
javac -sourcepath src -classpath bin -d bin C:\work\workspace\Project21\src\org\home\project21\study\designPatterns\LoginTester.java
java -classpath bin org.home.project21.study.designPatterns.LoginTester > ObserverPattern_output.txt
Finally the Output

Observer notes Alan Stair has logged In @ Sun Dec 09 22:34:21 IST 2012 sun.util.calendar.ZoneInfo[id="Asia/Calcutta",offset=19800000,dstSavings=0,useDaylight=false,transitions=6,lastRule=null]
Observer notes Alan Stair has logged In @ Sun Dec 09 22:34:21 IST 2012 sun.util.calendar.ZoneInfo[id="Asia/Calcutta",offset=19800000,dstSavings=0,useDaylight=false,transitions=6,lastRule=null]

Design Patterns : Observer Pattern 1

These days I have been learning design patterns. Since Singleton and Factory are already done to death with, I decided to choose a somewhat obscure one. Observer pattern.

Let's say we have a bean User which implements the below interface


package org.home.project21.study.designPatterns;

/**
 *
 *
 * @author Sanjay
 *
 */
public interface IUser {


    /**
     *
     *
     * @return
     */
    public String getUserName();
}
 
and which is intended to log a user into an interface like something below

package org.home.project21.study.designPatterns;

/**
 *
 *
 * @author Sanjay
 *
 */
public interface ILogUser {

    /**
     *
     *
     *
     * @param userName
     * @param password
     * @return
     */
    public IUser login(String userName, char [] password);
   
    /**
     *
     *
     *
     *
     * @param userName
     * @param password
     * @return
     */
    public IUser logout(String userName, char [] password);
   
    /**
     *
     *
     *
     * @return
     */
    public boolean isLogged(IUser user);
}
 



Now we would like to keep an eye on who logs on to the System. So we decide to create an observable system. Fortunately for us Java has already created a class 
  Observable which can be used for the purpose. For clarity we would extend it. Next we need an Observer class which will intimate us when it notices something 'Observable'. 


package org.home.project21.study.designPatterns;

import java.util.Calendar;
import java.util.Observable;
import java.util.Observer;

/**
 *
 * This class implements the Observer
 *
 * @author Sanjay
 *
 */
public class LoginObserver implements Observer {

    /**
     *
     *
     */
    @Override
    public void update(Observable arg0, Object arg1) {
        // TODO Auto-generated method stub
        ILogUser loginObservable = (ILogUser) arg0;
        IUser user = (IUser) arg1;
        System.out.println(" Observer notes " + user + " has " + (loginObservable.isLogged(user)?" logged In ":" logged Out ")
                + " @ " + Calendar.getInstance().getTime() + " " + Calendar.getInstance().getTimeZone());
    }

}




The observer class will update the System whenever the update method is invoked.

Now let us turn our attention to the main class The actual Observable. Since it is relatively bigger we would take it chunk by chunk. For completeness below is the source code


package org.home.project21.study.designPatterns;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Observable;
import java.util.Observer;

/**
 *
 * This class extends the Observable Class
 *
 * @author Sanjay
 *
 */
public class LoginObservable extends Observable implements ILogUser  {
   
    private List observers;
    private Map currentUsers_;
   
    private boolean changed;
   
    public boolean isLogged(IUser user) {
        if(currentUsers_ != null && currentUsers_.containsKey(user.getUserName())) return true;
        else return false;
    }


   
    /**
     *
     *
     *
     */
    public IUser login(String userName, char [] password) {
        // check pss
        changed = true;
        IUser user = new User(userName);
        if(currentUsers_ == null) {
            currentUsers_ = new HashMap();
        }
        currentUsers_.put(userName, user);
        notifyObservers(user);// notify all Observers of this user
        return user;
    }
   
    /**
     *
     *
     *
     *
     */
    public IUser logout(String userName, char [] password) {
        // check pss
        changed = true;
        IUser user = null;
        if(currentUsers_ != null) {
            if(currentUsers_.containsKey(userName)) {
                //double check pss
                user = currentUsers_.get(userName);
                currentUsers_.put(userName, null);
            }
        }
        notifyObservers(user);// notify all Observers of this user
        return user;
    }
   


    /**
     *
     *
     *
     */
    public LoginObservable() {
        // TODO Auto-generated constructor stub
        super();
        observers = new ArrayList();
        changed = false;
    }
   
   
    @Override
    public synchronized void addObserver(Observer o) {
        // TODO Auto-generated method stub
        if(observers != null) {
            observers.add(o);
        }
        else {
            throw new NullPointerException("observers == " + observers);
        }
    }
   
    @Override
    public synchronized int countObservers() {
        // TODO Auto-generated method stub
        if(observers != null) {
            return observers.size();
        }
        else {
            throw new NullPointerException("observers == " + observers);
        }
    }
   
    @Override
    public synchronized void deleteObserver(Observer o) {
        // TODO Auto-generated method stub
        if(observers != null) {
            if(observers.contains(o)) {
                observers.set(observers.indexOf(o), null);
            }
            else {
                throw new IllegalArgumentException( o + " not found in " + observers);
            }
        }
        else {
            throw new NullPointerException("observers == " + observers);
        }
    }
   
    @Override
    public synchronized void deleteObservers() {
        // TODO Auto-generated method stub
        if(observers != null) {
            observers = null;
           
        }       
        observers = new ArrayList();
    }
   
    @Override
    public boolean equals(Object obj) {
        // TODO Auto-generated method stub
        if(obj instanceof LoginObservable) {
            if(((LoginObservable)obj).observers != null && this.observers != null) {
                return this.observers.equals(((LoginObservable)obj).observers);
            }
            else {
                return false;
            }
        }
        return false;
    }
   
    @Override
    public synchronized boolean hasChanged() {
        // TODO Auto-generated method stub
        return changed;
    }
   
    @Override
    public void notifyObservers() {
        // TODO Auto-generated method stub
        this.notifyObservers(null);
    }
   
    @Override
    public void notifyObservers(Object arg) {
        // TODO Auto-generated method stub
        Observer [] observersArray =  new Observer[observers.size()];
        int count = 0;
        for(Observer observer : observers) {
            observersArray[count++] = observer;
        }
       
        if(this.hasChanged()) {
            for(Observer observer : observersArray) {
                observer.update(this, arg);
            }
        }
        clearChanged();
        observersArray = null;
    }
   
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return " observers " + this.observers.toString();
    }
   
    @Override
    protected synchronized void clearChanged() {
        // TODO Auto-generated method stub
        changed = false;
    }
}