CSC/ECE 517 Fall 2011/ch4 4h as

From Expertiza_Wiki
Jump to navigation Jump to search

Introduction

Software Design Patterns

Singleton Pattern

In software engineering the singleton pattern is a creational pattern which is used to ensure that not more than one object is ever created for a class. The singleton also provides a point of global access.

Common Applications

There may be various reasons that necessitate such a requirement for a class.The class may represent the global state of the system or the class may correspond to a master logger which writes into the log file. Some other places where the singleton pattern is applicable are device drivers, registry settings, etc.

Implementation

There are many ways of implementing the singleton pattern. The most common way is to have a method which creates an instance of the object if it does not already exist. Otherwise the existing reference is returned. To make sure that multiple instances are not created the constructor is made private. Also the object which stores the single instance is made a class variable and is thus not tied to any particular instance of the class.

public class Singleton {
    private static Singleton singletonInstance;
    private Singleton() {  }
    public static Singleton getInstance() {
            if (singletonInstance == null) {
                   singletonInstance = new Singleton();
            }
            return singletonInstance;
    }
}

This is an example of lazy instantiation where the object is not created until the first time it is required. Though the above implementation is straight forward, it does not work in a multi threaded environment. If two threads call the getInstance method at the same time, race conditions may result in more than one instance of the class being created, violating the singleton pattern. This problem can be easily solved by making the 'getInstance' method mutually exclusive using locks. In JAVA this is easily achieved by making the 'getInstance' method synchronized.

Alternatively we could replace

    private static Singleton singletonInstance; 	          

with

    private static Singleton singletonInstance = new Singleton();

This is an example of eager instantiation and it has a pitfall of wasting memory space if the Singleton object never ends up being used. However it should also be noted that this version is thread safe because the singletonInstance is created as soon as the Singleton class is loaded by the class loader.

The above examples present a very common way of implementing the singleton pattern. This is by means an exhaustive list of possible implementations. There are additional methods of achieving the same result such as “double checked locking” and using enum data-type

Adapter Pattern

The adapter pattern, also called wrapper pattern, is used to enable two classes with incompatible interfaces to work together without modifying either class. Adapters are common in real world objects, the most common example being electrical socket adapters which enable electrical appliances from one country to work in another country.

Common Applications

Command Pattern

Command Pattern focuses on one important aim: To ensure that the object calling a method is completely unaware of how the method is called, implemented and handled. In other words, it aims at achieving decoupling of the caller and the function being called. Let us consider a real world example to better understand this pattern. Suppose we have a magical drop-box which has the note “Drop and it will be done”. We will be really happy to just drop of errands like ‘Do my Homework’, ‘Pick up my Laundry’ and many more! The point to consider here is that we are calling an unknown function by dropping errands – unknown to us in terms of implementation details – but with a common crystallized interface – The Drop Box! We as invokers are not concerned about how our homework is done or how our laundry is picked up as long it is done and picked up. We are just concerned to drop off our requests into the Box and let it do the rest. This is precisely what Command Pattern achieves. Now the sections below will explain how exactly the pattern goes about achieving this aim.

The command pattern consists of the following parts/participants: • Command This is an interface which provides the common function (execute) to the Invoker. Thus, the invoker knows that it can carry out the required action using this execute function. This is the interface where additional operations can be declared so that they are available to the invoker. This is the crystallized interface that was mentioned in the above example.

• Invoker Invoker holds the Command object and when required calls the execute operation of the Command to fulfill the required request.

• Receiver Receiver is the enlightened one and knows the actual logic of carrying out the required function/request. The receiver is the one who will receive the request through the execute function invoked by the invoker. Any class can act as a receiver.

• CommandObject The CommandObject is the one which implements the execute function of the Command interface. The CommandObject or ConcreteCommand binds the execute function and the action of the Receiver to be invoked. Thus, this object is the one who actually calls the required action(s) of the Receiver.

• Client Client creates the required CommandObject and sets its Receiver. Thus, the Client will decide as to which Command will actually be executed. The point to note here is that different commands can have different CommandObjects.


The above diagram gives a gist of how the command pattern works. Here is what happens. 1. The Client creates the CommandObject which contains the execute function from the Command interface. The CommandObject provides a specific implementation to the execute function in such a way that it binds a set of receiver actions to the execute function in this CommandObject. This execute can be used to invoke the encapsulated actions of the receiver at any time.

2. The Client further invokes the set-Command method which passes the CommandObject to the Invoker as an argument thereby saving the CommandObject reference within the Invoker. Thus, the CommandObject is now stored in the Invoker for any further use. This Object can be used by the Invoker to call the actions on the Receiver whenever the Client asks for it.

3. Now, the Client decides to ask the Invoker to execute the command. Note that the command can stay in the Invoker as long as required and as long as it is not replaced by a different command. Thus, it can be kept or discarded at any point of time.

4. The Invoker calls the CommandObject’s execute method. Note that the invoker only knows about the execute method at this point of time and nothing else. This ensures decoupling between the invoker object and the receiver object.

5. Once the invoker calls execute, the execute function in the CommandObject is executed which in turn contains encapsulated methods of the Receiver Object. These methods are called and the operation is completed. Note here that the CommandObject should hold a reference to the Receiver class for it to actually have the ability to call Receiver’s functions. This setting is controlled and done by the Client.

Formal Definition of Command Pattern The Command Pattern encapsulates a request as an object and thereby allows us to parameterize other objects with different requests, queue or log requests and support undoable operations. [should have link to the Book or Wikipedia]

Pros and Cons 1. The Command Pattern successfully decouples the object which invokes the operation from the object which actually performs the operation. 2. CommandObjects are like normal first-class objects. They can be easily extended, manipulated and handled like every other object. 3. The Command pattern can easily handle an undo operation. By maintaining a history of the commands executed, we can undo the last operations in the order that they were performed. 4. The Command pattern lets us create a group of operations to be performed in one call of execute. This functionality is called as MacroOperations or Composite Commands. Such commands consist of multiple actions related to different Receivers which can be performed one after the other on just one invocation. 5. Due to the excellent structure of the Command pattern, it is easily extensible and hence it is easy to declare and add new Commands.

Implementation through Example:

public class Homework { public void doHomework(){ System.out.println("Homework is done."); } }

public interface Command { public void execute(); }

public class HomeworkCommand implements Command { Homework homework; public setHomework(Homework homework){ this.homework = homework; }

public void execute(){ homework.doHomework(); } }

public class Invoker { Command command; // Command is referenced by the common interface. public void setCommand(Command command){ this.command = command; }

public void performAction(){ command.execute(); } }

public class Client { public static void main(String args[]){ Homework homework; Invoker invoker; HomeworkCommand hwCommand = new HomeworkCommand(); hwCommand.setHomework(homework); //Set the Receiver invoker.setCommand(hwCommand); // Set Command to Homework. Any other commands can be used. invoker.performAction(); // Will execute Homework's execute. } }

Command Pattern in Ruby Command Pattern in Ruby can be accomplished by using Procs. Procs are procedures which consist of binding of variables in its scope when it is created. When we call any Proc, it is not necessary for the caller to know the internal details of the Proc or how it is implemented. The caller just has to pass the required arguments and get the output. This ensures the decoupling of the caller from the method. Procs make is easy to implement the Command Pattern efficiently in Ruby.

Strategy Pattern

Conclusion

References