Saturday, April 30, 2011

Design Patterns(Singleton, Decorator, Immutable Class)

Hey...

In software engineering, a design pattern is a general reusable solution to a commonly occurring problem in software design. A design pattern is not a finished design that can be transformed directly into code. It is a description or template for how to solve a problem that can be used in many different situations. Object-oriented design patterns typically show relationships and interactions between classes or objects, without specifying the final application classes or objects that are involved. Here I will introduce 3 design patterns. More design patterns are available in my future posts.

1. Singleton
1.1 Pattern Goal
This Pattern make an object to be created once in whole application life cycle. If you want any thread or request uses and shares only one instance of indicated object you can apply this pattern. This pattern deals with concurrency problem of critical sections in class methods. Thus, take care of concurrency whenever you use this pattern as a solution.
1.2 Pattern Detail
To make a class have single object in application scope, we should make the constructor of the class, private. This prevents of creating the class.
public class TestClass{
    private TestClass() {
    }
}
Then we make a private static instance of the class and initiate it in an static method. In this method we should check if the static field has been initiated or not. If yes we shouldn't do that.
    public class TestClass {
        private static TestClass testClass;

        private TestClass() {
        }

        public static TestClass getInstance() {
            if (testClass == null) {
                testClass = new TestClass();
            }
            return testClass;
        }
    }
That's it. The pattern is complete. To use this class, you must not new it. you can use getInstance method.
...
TestClass testClass = TestClass.getInstance();
testClass.customMethod();
...
1.3 Pattern Sample
We want to know how many times a button is clicked. Here is the class to save click count.




I create a class called ClickButton then apply singleton pattern to it. Any time button is clicked we should run click method of this class. Here is the code:
public class ClickButton {
    private static ClickButton clickButton;
    Integer clickCount;

    private ClickButton() {
        clickCount = 0;
    }

    public static ClickButton getInstance() {
        if (clickButton == null) {
            clickButton = new ClickButton();
        }
        return clickButton;
    }

    public void click() {
        synchronized (clickCount) {
            clickButton.clickCount++;
        }
    }

    public Integer getClickCount() {
        return clickButton.clickCount;
    }
}
and here is the use of this class:
@Controller
@Scope("prototype")
@RequestMapping("/button")
public class ButtonController {

...
    @RequestMapping("/click")
    public String click(@ModelAttribute("button")ClickButton clickButton, HttpServletRequest request) {
        clickButton.click();
        request.setAttribute("clickcoutn", clickButton.getClickCount());
        return "button.view";
    }
...
}
and here is the result:

2. Decorator
1.1 Pattern Goal
Attach additional responsibilities to an object dynamically keeping the same interface. Decorators provide a flexible alternative to subclassing for extending functionality. On the other hands we can decorate a class dynamically. For example a simple coffee class has only coffee as ingredients. But we will be able to add milk, sugar, ... to it dynamically when apply this patter.

1.2 Pattern Detail
We should make an interface and a simple form of class implementing the interface. Another class is decorated class implementing the interface. The decorator class should contains a protected object of the interface and initiate it in its constructor. In implementation of the interface methods, We should just call and return the related method of the protected field. The decorator class should be an abstract class to prevent directed usage.
Now you can create other classes extending decorator class. Then override the interface methods of the decorator class in your custom class and do any decoration to the methods. Here is the pattern structure:

1.Interface:
public interface TestClass{
    Object testMethod();
}
2.Simple Form:
public class SimpleTestClass implements TestClass{
    public Object
testMethod() {
        return Do something;
    }

3.Decorator Class:
public abstract class DecoratorTestClass implements TestClass{
    protected
TestClass testClass;

    public
DecoratorTestClass(TestClass testClass) {
        this.
testClass = testClass;
    }

    public
Object testMethod() {
        return
testClass.testMethod();
    }
}
4.Custom Class:
public class CustomTestClass1 extends DecoratorTestClass{
    public
CustomTestClass1(TestClass testClass) {
        super(
testClass);
    }

    @Override
    public Object
testMethod() {
        Object test = super.
testMethod();
        do something with test
        return
test;
    }
}


public class CustomTestClass2 extends DecoratorTestClass{
    public CustomTestClass2(TestClass testClass) {
        super(testClass);
    }

    @Override
    public Object testMethod() {
        Object test = super.testMethod();
        do something with test
        return test;
    }
}

...
public class CustomTestClassN extends DecoratorTestClass{
    public CustomTestClassN(TestClass testClass) {
        super(testClass);
    }

    @Override
    public Object testMethod() {
        Object test = super.testMethod();
        do something with test
        return test;
    }
}
5. Use of Decorator Class:
public class TestController {
public Object TestMethod(){
        TestClass test = new CustomTestClass2(new CustomTestClass5(new CustomTestClass7(new SimpleTestClass())));
        return test.testMethod();
    }
}

1.3 Pattern Sample
House List example is a sample that works with house class. House class has two methods including getFacilityLIST() and getPrice(). I'm going to apply decorator pattern to these two methods. Some facilities will be apply to the basic house and its price gets more dynamically. Here is the class diagram:
and here is the source code:
1. Interface:
public interface House {
    List<String> getFacilityLIST();
    Long getPrice();
}
2. Simple Class:
public class SimpleHouse implements House{
    public List<String> getFacilityLIST() {
        List<String> facilityList = new ArrayList();
        facilityList.add("Building");
        facilityList.add("Restroom");
        facilityList.add("Kitchen");
        facilityList.add("Salon");
        return facilityList;
    }

    public Long getPrice() {
        return 1000l;
    }
}
2. Decorator Class:
public abstract class DecoratorHouse implements House{
    protected House decoratedHouse;

    public DecoratorHouse(House decoratedHouse) {
        this.decoratedHouse = decoratedHouse;
    }

    public List<String> getFacilityLIST() {
        return decoratedHouse.getFacilityLIST();
    }

    public Long getPrice() {
        return decoratedHouse.getPrice();
    }
}
3. Custom Classes:
public class SingleRoomHouse extends DecoratorHouse{
    public SingleRoomHouse(House decoratedHouse) {
        super(decoratedHouse);
    }

    @Override
    public List<String> getFacilityLIST() {
        List<String> facilityList = super.getFacilityLIST();
        facilityList.add("1 Room");
        return facilityList;
    }

    @Override
    public Long getPrice() {
        return super.getPrice() + 200l;
    }
}


public class DoubleRoomHouse extends DecoratorHouse{
    public DoubleRoomHouse(House decoratedHouse) {
        super(decoratedHouse);
    }

    @Override
    public List<String> getFacilityLIST() {
        List<String> facilityList = super.getFacilityLIST();
        facilityList.add("2 Rooms");
        return facilityList;
    }

    @Override
    public Long getPrice() {
        return super.getPrice() + 400l;
    }
}


public class CompleteHouse extends DecoratorHouse{
    public CompleteHouse(House decoratedHouse) {
        super(decoratedHouse);
    }

    @Override
    public List<String> getFacilityLIST() {
        List<String> facilityList = super.getFacilityLIST();
        facilityList.add("Gardened Yard");
        facilityList.add("Car Parking");
        return facilityList;
    }

    @Override
    public Long getPrice() {
        return super.getPrice() + 1000l;
    }
}


public class ModernHouse extends DecoratorHouse{
    public ModernHouse(House decoratedHouse) {
        super(decoratedHouse);
    }

    @Override
    public List<String> getFacilityLIST() {
        List<String> facilityList = super.getFacilityLIST();
        facilityList.add("Closet");
        facilityList.add("Pool");
        return facilityList;
    }

    @Override
    public Long getPrice() {
        return super.getPrice() + 1000l;
    }
}

3. Immutable Object
1.1 Pattern Goal
To make an object read only or even make an object read only in some places of you application, you can apply this pattern to you classes.

1.2 Pattern Detail
First of all you should make a wrapper to your class. We call this wrapper class, Immutable Class. The Immutable Class should have a private final field with the indicated class data type and initiate it in the constructor. Then make a getter for that. In the getter method you should return a clone of the field. This make a new instance of the object and this make the object read only. Whenever you get the object from this method a new instance will be make so the object which is passed from the constructor will stay safe and won't be changed.
Note: Your Object should be cloneable
Take a look to these codes:
Base class:
public class TestClass implements Cloneable{
    String field1;

    public
TestClass(String field1) {
        this.
field1= field1;
    }

    public String get
Field1() {
        return name;
    }

    public void setF
ield1(String field1) {
        this.
field1= field1;
    }

    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
Immutable class:
public class ImmutableTestClass {
    private final
TestClass testClass;

    public
ImmutableTestClass(Student testClass) {
        this.
testClass= testClass;
    }

    public
testClass getTestClass() throws CloneNotSupportedException {
        return (
TestClass) testClass.clone();
    }
}

1.3 Pattern Sample
Student class is an entity bean class. I will make it Immutable and show you if you change the object, even manually, the major object will be never changed. Here is the class diagram:

 

And here is the source code:
Entity Bean:
public class Student implements Cloneable{
    String name;
    String stNo;
    Float gpa;

    public Student(String name, String stNo, Float gpa) {
        this.name = name;
        this.stNo = stNo;
        this.gpa = gpa;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getStNo() {
        return stNo;
    }

    public void setStNo(String stNo) {
        this.stNo = stNo;
    }

    public Float getGpa() {
        return gpa;
    }

    public void setGpa(Float gpa) {
        this.gpa = gpa;
    }

    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
Immutable Class:
public class ImmutableStudent {
    private final Student student;

    public ImmutableStudent(Student student) {
        this.student = student;
    }

    public Student getStudent() throws CloneNotSupportedException {
        return (Student) student.clone();
    }
}
Use of Immutable Class:
@Controller
@Scope("prototype")
@RequestMapping("/student")
public class StudentController {
    @ModelAttribute("student")
    public ImmutableStudent studentModel() {
        return new ImmutableStudent(new Student("Mostafa Rastgar", "2020041251", 15.2f));
    }

    @RequestMapping("/view")
    public String view() {
        return "student.view";
    }

    @RequestMapping("/save")
    public String save(@ModelAttribute("student") ImmutableStudent immutableStudent, @RequestParam(value="student.name", required = true) String name, @RequestParam(value="student.stNo", required = true) String stNo, @RequestParam(value="student.gpa", required = true) Float gpa, HttpServletRequest request) throws CloneNotSupportedException {
        Student student = immutableStudent.getStudent();
        student.setName(name);
        student.setStNo(stNo);
        student.setGpa(gpa);
        request.setAttribute("studentParam", student);
        return "student.view";
    }
}
As you see, although the value of entity fields will be set manually(red lines), but the student shown in the form will stay in its init value(the value which is set in studentModel method) and never change. Because we use immutableStudent.getStudent() in save method and it makes a new instance from the object which is passed into its constructor.

Source Code
You can download those 3 samples from here. After the deployment the start page is: http://localhost:8080/button/view.html



all rights reserved by Mostafa Rastgar and Programmer Assistant weblog

4 comments:

omidbiz said...

Hi,
In singleton pattern maybe it's better to synchronized method instead of static field before you screw the class :D WYT?

public synchronized void click(){
clickBtton.clickCount++;
}

mostafa rastgar said...

dude, ur exactly right

omidbiz said...

one more thing, I'm just wondering in immutable pattern why do u implements Cloneable interface in TestClass cause every class has clone() method as an object is it really necessary ?

mostafa rastgar said...

I implement Cloneable and override clone() method, because to make a class cloneable we should do it. clone method is a protected method of Object class. To make it public we should override it. If a class does not implements Cloneable, exception will be raised in clone() method.