Hard-Coding a fixed set of behaviours toward defining a
smaller set of fundamental behaviours that can be composed in to any number of more complex ones. [GOF]
Pattern which defines the composition of classes and objects in the system to build the desired structure is known as Structural Pattern. Structural patterns define a way to combine two or more independent developed libraries. Developed libraries may differ in their implementation but can work for each other to produce the desired result without knowing the internal details.
For example, a particular Car model can make use of the cooling system to provide A/C feature though the cooling system is developed independent of the Car model.
One example of the structural pattern is Adapter pattern. Adapter pattern promotes the development of one interface to a particular implementation in order to provide uniform abstraction of different interfaces. Adapter pattern is particularly useful when you have two different classes with incompatible interfaces.
There are 3 entities to participate in the Adapter pattern. If a class wants to make use of an implementation, then these classes can be named as Target and Adaptee, respectively. The wrapper which provides the requested operations by the target using the implementation of the Adaptee is called Adapter. Below is the interaction diagram between Target, Adapter and Adaptee.
Implementation
Let’s take the example of Stack implementation.
Suppose Stack interface is exposed to the client to support stack data structure and operations. Now, there is a need to implement the Generic stack data structure. One possible approach is to use generic dictionary to implement generic stack. Generic dictionary is the class implemented in library to support generic and retrieval and storage of the items.
We can classify stack interface exposed to the client as Target and Dictionary class as an Adaptee. Create a wrapper class (GenericStack) which takes the responsibility to implement the stack operations using dictionary class. One of the possible implementation will follow the structure shown in the below image.
Code:
Stack Interface
/// /// To Push Item in the Stack /// void Push(T item); /// /// Pop up the given item from the Stack /// T Pop();
/// To Pop up the item from the Stack T[] Pop(T item); } } |
Generic Stack
class
where T :
{ #region Fields
} } ///
public T Pop()
#endregion Methods } |
Client:
{ #region Fields private
#endregion Fields #region Properties #endregion Properties #region Methods public Client(IStack<int> stack) { this.stack = stack; } /// /// To Simulate Operations on Stack ///
internal
{ int item; Console.WriteLine("Push: 5"); stack.Push(5); Console.WriteLine("Push: 4"); stack.Push(4); item = stack.Pop(); Console.WriteLine("Pop: " + item); Console.WriteLine("Push: 3"); stack.Push(3); item = stack.Pop(); Console.WriteLine("Pop: " + item); item = stack.Pop(); Console.WriteLine("Pop: " + item); item = stack.Pop(); Console.WriteLine("Pop: " + item); } #endregion Methods } |
Main Method:
{ static
{ IStack<int> stack =
} } |
** Please note that above implementation relies on the Hash code of the object in the stack. Results may be unpredictable if GetHashCode() method has been overridden in object’s type.
No comments:
Post a Comment