Application Architecture: Software Applications come in all shapes and sizes. Based on their design and architecture enterprise applications can be classified into various categories such as: * * * *
Distributed Applications Web Applications Web Services Smart Client Applications
This article reviews some of the architecture Design patterns for Enterprise Applications built using the .NET Platform.
Simply put Application architecture is: - Set of significant decisions about how a software system is organized - Selection of the elements that the system comprises of - Interfaces of the elements - Behavior of these elements - Interaction of these elements within the system and with other systems What are Design Patterns? A Software design pattern provides us a general solution to a common problem in software design. It is a description or template for how to solve a problem. Large majority of Software development teams tend to face similar problems in Software development. Patterns provide us reusable solutions to commonly encountered programming challenges This helps us speed up the Design and overall Development Time and Effort thereby resulting in cost savings. At the same time since these patterns are time tested they provide solutions with known benefits and drawbacks. Over a period of time patterns get improvised and new patterns emerge. There are various types of Software Design Patterns: Design patterns can be classified based on multiple criteria, the most common of which is the basic underlying problem they solve.
List below are some of the most important categories of Software Design Patterns: A) Creational patterns: Creational design patterns deal with object creation mechanisms B) Structural patterns: Structural design patterns focus on relationships/interfaces between entities and objects C) Behavioral patterns: Behavioral design patterns focus on common communication patterns between objects.
Design Patterns on the .NET Platform: Some of the design patterns used with .NET : A) Creational Patterns: * * * * *
Factory Method Abstract Factory Builder Prototype Singleton
B) Structural Patterns: * * * *
Adapter Bridge Composite Proxy
C) Behavioral Patterns: * Iterator * Observer
Creational Patterns : * * * * *
Factory Method Abstract Factory Builder Prototype Singleton
Category : Creational Pattern Pattern : Factory Design Brief Description : This being a ‘creational design pattern’ it focuses on how the objects are created. In the Factory design pattern – the client uses a specialized object solely to create other objects. In the diagram, you would observe that the object (“product”) creation process is handled by the “Factory” object and it is abstracted from the “client” object. Flow Illustration :
Why would anybody use such a design pattern? Imagine you are writing the code for the “Client” object. The “client” object needs to use the “Product” object. You hard code the object creation process in the “Client” Now any changes in the object creation procedure would mean that you need to change the “client” too. The sole purpose of the “Factory” object is to create “Product” This gives us a certain amount of flexibility. The “client” delegates that task to “Factory”. Any changes in the object creation process do not affect the “client” and changes to “Factory” should be fairly simple as that is the only thing it does.
//Creational Pattern: The Factory Method //Author:
[email protected] /* In Factory method pattern, A Factory class contains a factory method is used for creating the object. This factory method can be either static or non-static. */ using System; class Factory { public Base GetObject(int type) { Base base1 = null; switch(type) { case 1: base1 = new Derived1(); break; case 2: base1 = new Derived2(); break; } return base1; } } interface Base { void DoIt(); } class Derived1 : Base { public void DoIt() { Console.WriteLine("Derived 1 method"); } } class Derived2 : Base { public void DoIt() { Console.WriteLine("Derived 2 method"); } }
//Client class //Client class needn’t know about instance creation. The creation of Product is //deferred to the Factory class class MyClient { public static void Main() { Factory factory = new Factory();//Decides which object must create. Base obj = factory.GetObject(2); obj.DoIt(); } } Category : Creational Pattern Pattern : Abstract Factory Brief Description : Imagine a bakery that has an oven for baking different types of cakes. The overall process of baking different types of cake is similar and the same oven creates all types of cakes. The only limitation is that the cake should ‘fit’ in the oven. When the oven was created it was created to bake any type of cake/pie/bread/etc that would fit in it. Once you have the oven you can create any of these. The oven does not have the recipe for creating a specific cake. You have the recipe and you supply different ingredients to it and with a few variations/changes to the process different types of cakes are produced. Similarly, The Abstract Factory pattern provides an interface for creating families of related or dependent classes without having to specify the actual classes. The Abstract Factory Design Pattern provides a single interface to create a family of related objects. The family members (“concrete classes”) are specified elsewhere. The Abstract Factory uses “Factory Methods” to create the specific objects. The Factory Methods are in a separate class. Illustration :
Where it is used? The Abstract Factory is used to develop frameworks and systems that can be configured with one of multiple families of products (UI controls, menus, toolbars, etc.)
// Creational Pattern: Abstract Factory Pattern /* In the following snippet, implementation of this
Factory
is
an
interface.
The
concrete
interface ConcreteFactory1 and ConcreteFactory2 implements the method getObject so that it returns Derived1 and Derived2 objects respectively. The Base is an interface and Derived1 and Derived2 are the concrete implementations of the base class. The client (MyClient class) always uses the Factory implementations to create an instance of the Base classes. Actually the derived classes of Factory interface decided which object (either Derived1 or Derived2) has to be created. */ using System; interface Factory { Base GetObject(); } //This class is responsible for creating objects of the class Derived1. class ConcreteFactory1 :Factory { public Base GetObject() {return new Derived1(); } } //This class is responsible for creating objects of the class Derived2. class ConcreteFactory2 : Factory { public Base GetObject() {
return new Derived2(); }} interface Base { void DoIt(); } class Derived1 : Base { public void DoIt() { Console.WriteLine("Derived 1 method"); } } class Derived2 : Base { public void DoIt() { Console.WriteLine("Derived 2 method"); } } /* Client class Client class needn’t know about instance creation. The creation of Product is deferred to he ConcreteFactory1. */ class MyClient { public static void Main() { Factory factory = new ConcreteFactory2();//Decides which object must create. Base obj = factory.GetObject(); obj.DoIt(); } }
Category : Creational Pattern Design Pattern : Builder Brief Description : Highlights of the Builder Design Pattern are: - This is a Creational Design Pattern and focuses on how the objects are created - Complex objects are created in parts as needed - Finally the parts can be put together to obtain the final result or the product Illustrations :
Class Diagram
//Creational Pattern: BUILDER using System; class Director { public void Construct(IBuilder builder) { builder.DoIt(); } } interface IBuilder { void DoIt(); } class BuilderA : IBuilder { public void DoIt() { //Necessary code for building the computer type A Console.WriteLine("Assembly a Computer with mono monitor"); } } class BuilderB : IBuilder { public void DoIt() { //Necessary code for building the computer type B Console.WriteLine("Assembly a Computer with color monitor"); } }
class MyClient { public static void Main() { Director d = new Director(); IBuilder build = new BuilderA(); d.Construct(build); } }
Category : Creational Pattern Design Pattern : Prototype Brief Description : Highlights of the Prototype Design Pattern are: - This is a Creational Design Pattern and focuses on how the objects are created - An object is instantiated and can be called a prototype - As needed the above object is cloned and new objects are created - The new objects are copies of the original one i.e. the protoype
The prototype pattern is used when creating an instance of a class is very time consuming or complex in some way. Then rather than creating more instances, it is possible to make copies of the original instances and modifying them as appropriate. When we are not in a position to call a constructor for an object directly, we could alternatively clone a pre-existing object (a prototype) of the same class. When there are many subclasses that differ only in the kind of objects they create a Prototype Pattern can be used to reduce the number of subclasses by cloning a prototype. Prototype Design Pattern helps in reducing number of classes. Illustrations :
Category : Creational Pattern Design Pattern : Singleton Brief Description : The singleton design pattern is used when only one instance of an object is needed throughout the lifetime of an application. The singleton class is instantiated at the time of first access and the same instance is used thereafter till the application quits. The Singleton class can be used in various places where one would need a common repository of information that can be accessed from all objects in an application. For example sometimes we may need a single Database connection object or Network connection object In nearly every application, there is a need to have an area from which to globally access and maintain some type of data. There are also cases in object-oriented (OO) systems where there should be only one class, or a predefined number of instances of a class, running at any given time. For example, when a class is being used to maintain an incremental counter, the simple counter class needs to keep track of an integer value that is being used in multiple areas of an application. The class needs to be able to increment this counter as well as return the current value. For this situation, the desired class behavior would be to have exactly one instance of a class that maintains the integer and nothing more. At first glance, one might be tempted to create an instance of a counter class as a just a static global variable. This is a common technique but really only solves part of the problem; it solves the problem of global accessibility, but does nothing to ensure that there is only one instance of the class running at any given time. The responsibility of having only one instance of the class should fall on the class itself and not on the user of the class. The users of the class should always be free from having to monitor and control the number of running instances of the class. What is needed is a way to control how class instances are created and then ensure that only one gets created at any given time. This would give us exactly the behavior we require and free a client from having to know any class details.
Highlights of the Singleton Design Pattern are: - This is a Creational Design Pattern and focuses on how the objects are created - The first time the object is needed an instance is created - Further requests to create/access the object are redirected to the original instance - The Singleton Design Pattern ensures that there exists only one instance of the object The model for a singleton is very straightforward. There is (usually) only one singleton instance. Clients access the singleton instance through one well-known access point. The client in this case is an object that needs access to a sole instance of a singleton. Figure 1 shows this relationship graphically.
Illustrations
:
Here we created a Singleton class that maintains an incremental count with a type long. The client is a simple console application that displays twenty values of the counter class.
sealed class SingletonCounter { public static readonly SingletonCounter Instance = new SingletonCounter(); private long Count = 0; private SingletonCounter() {} public long NextValue() { return ++Count; } } class SingletonClient { [STAThread] static void Main() { for (int i=0; i<20; i++) { Console.WriteLine("Next singleton value: {0}", SingletonCounter.Instance.NextValue()); } } }
Structural and Behavioral Design Patterns In this tutorial you will learn about Structural Patterns - Adapter, Bridge, Composite and Proxy. You will also learn about Behavioral Patterns - Iterator and Observer. Category : Structural Pattern Design Pattern : Adapter Brief Description : Highlights of the Adapter Design Pattern are: - This is a Structural Design Pattern and focuses on how the objects interact - relationships/interfaces between entities and objects - The key players are •
Generic Object with its interface
•
Client specific Object with client specific interface
•
Adapter Object that adapts the generic interface to the client specific interface
llustration :
Category : Structural Pattern Design Pattern : Bridge Brief Description : Highlights of the Bridge Design Pattern are: - This is a Structural Design Pattern and focuses on the relationships/interfaces - between entities and objects - This pattern provides a certain amount of flexibility by providing a level of -
abstraction to animplementation An object (say “Implementor”) implements the functionality The client object does not call the “Implementor” Object directly it calls a Wrapper object which in turn calls the “Implementor” Thus the Wrapper can provide Value additions to the data returned by Implementor
- The Wrapper can be changed without changing Implementor - The focus of this pattern is to decouple the implementation from the called or (referred to as the interface component wrapper) Illustration :
Category : Structural Pattern Design Pattern : Composite Brief Description : Highlights of the Composite Design Pattern are: - This is a Structural Design Pattern and focuses on the relationships/interfaces - between entitiesand objects - This pattern comprises of objects that form a tree pattern - A component may have one or more child components and they in turn may have - one or morechildren - For example in a XML document Each node may have one or more child nodes exactly like itself - The Composite design pattern is suited for scenarios such as these - Each component can have functionality to add, remove query children - An element class can provide functionality that could correspond to a “leaf” in the tree - The element class can be used to perform operations with a data value of that node - The focus of this pattern is to provide an object with an interface such that the object can have one or more children that have the exact same interface. The hierarchy continues recursively. It also provides a “leaf” object for the “tree” such that it represents any one of the nodes in the entire relationship tree Illustration :
Category : Structural Pattern Design Pattern : Proxy Brief Description : Highlights of the Proxy Design Pattern are: - This is a Structural Design Pattern and focuses on the relationships/interfaces between entities and objects - The Proxy object provides a level of isolation to the real object - The Proxy object represents the actual object, the proxy object is like a placeholder - The Proxy has the same interface as the “real” object - When a client call the “real” object the call can be routed through the proxy - This is useful in cases where the “real” object is on a different server - This is also useful if you do not wish to provide direct access to the “real” object and if you need to perform a security check before calling the “real” object - The focus of this pattern is to provide a placeholder object called proxy and the proxy has the same interface as the real object Illustration :
Category : Behavioral Pattern Design Pattern : Iterator Brief Description : Highlights of the Iterator Design Pattern are: - This is a Behavioral Design Pattern and focuses on the communication patterns between objects - The Iterator component provides a way to sequentially access a collection of objects - Once an Iterator is created the client access the objects in a collection using functions such as getfirst, getcurrent , getNext, etc. Illustrations :
Category : Behavioral Pattern Design Pattern : Observer Brief Description:
Highlights of the Observer Design Pattern are: - This is a Behavioral Design Pattern and focuses on the communication patterns between objects - The observer pattern comprises of an object that serves as an observer for certain events - One or more observer components are registered with a target object which can be termed as a “Subject” - If an event occurs such as a mouse click /change of value /etc it notifies the observer - The observer in turn can call methods/code to act when the event occurs
Illustrations :