Showing posts with label Design Pattern & OOPS. Show all posts
Showing posts with label Design Pattern & OOPS. Show all posts

Monday, March 26, 2018

Abstract Factory Pattern Using C# - Real World Example

While learning about design patterns, I came to understand the most frequently used term, Factory Pattern as well as Abstract factory pattern. I searched the internet and came across numerous learning points. After a lot of search and study, I endeavored to find an actual need for the abstract design pattern.

In this article, I will explore this pattern in an easy way so that everyone can have a better understanding of it. Down the level, I'm using a Car (Vehicle) example to demonstrate abstract factory pattern.

An important aspect of software design is the manner in which objects are created. Thus, it is not only important what an object does or what it models, but also in what manner it was created.

Reference: http://www.dofactory.com/
Definition
Provide an interface for creating families of related or dependent objects without specifying their concrete classes.

Definition

C#

I'd keep the structure in such a way as depicted below.
Participants

The classes and objects participating in this pattern are:

  • AbstractFactory (IVehicleFactory)
    • declares an interface for operations that create abstract products.
  • ConcreteFactory (MarutiFactory, TataFactory)
    • implements the operations to create concrete product objects.
  • AbstractProduct (ICarEngine, ICarLight)
    • declares an interface for a type of product object.
  • Product (DDis, LED, Revtron, Helogan)
    • defines a product object to be created by the corresponding concrete factory.
    • implements the AbstractProduct interface.
  • Client (Clinet)
    • uses interfaces declared by AbstractFactory and AbstractProduct classes.

Implementation

  1. using System; 
  2. namespace AbstractFactoryPattern 
  3. interface IVehicleFactory 
  4.     { 
  5.         ICarEngine GetCarEngine(); 
  6.         ICarLight GetCarLight(); 
  7.     } 
  8. class MarutiFactory : IVehicleFactory 
  9.     { 
  10. public ICarEngine GetCarEngine() 
  11.         { 
  12. return new DDiS(); 
  13.         } 
  14. public ICarLight GetCarLight() 
  15.         { 
  16. return new LED(); 
  17.         } 
  18.     } 
  19. class TataFactory : IVehicleFactory 
  20.     { 
  21. public ICarEngine GetCarEngine() 
  22.         { 
  23. return new Revtron(); 
  24.         } 
  25. public ICarLight GetCarLight() 
  26.         { 
  27. return new Helogen(); 
  28.         } 
  29.     } 
  30. class LED : ICarLight 
  31.     { 
  32. public string GetLightInfo() 
  33.         { 
  34. return "Led lights"; 
  35.         } 
  36.     } 
  37. class DDiS : ICarEngine 
  38.     { 
  39. public string GetEngineInfo() 
  40.         { 
  41. return "DDis engine for their diesal cars..."; 
  42.         } 
  43.     } 
  44.     internal class Helogen : ICarLight 
  45.     { 
  46. public string GetLightInfo() 
  47.         { 
  48. return "Helogan Light..."; 
  49.         } 
  50.     } 
  51.     internal class Revtron : ICarEngine 
  52.     { 
  53. public string GetEngineInfo() 
  54.         { 
  55. return "Revtron engine for their diesal/petrol cars..."; 
  56.         } 
  57.     } 
  58.     internal interface ICarLight 
  59.     { 
  60.         string GetLightInfo(); 
  61.     } 
  62.     internal interface ICarEngine 
  63.     { 
  64.         string GetEngineInfo(); 
  65.     } 
  66. class Client 
  67.     { 
  68. private IVehicleFactory vehicleFactory = null; 
  69. public void CreateCarWithLight(string carName) 
  70.         { 
  71. if (carName.ToLower() == "maruti") 
  72.             { 
  73.                 vehicleFactory = new MarutiFactory(); 
  74.                 Console.Write( 
  75.                     $"{carName} uses {vehicleFactory.GetCarEngine().GetEngineInfo()} with {vehicleFactory.GetCarLight().GetLightInfo()} as headlight"); 
  76.             } 
  77. else if (carName.ToLower() == "tata") 
  78.             { 
  79.                 vehicleFactory = new TataFactory(); 
  80.                 Console.Write( 
  81.                     $"{carName} uses {vehicleFactory.GetCarEngine().GetEngineInfo()} with {vehicleFactory.GetCarLight().GetLightInfo()} as headlight"); 
  82.             } 
  83.         } 
  84.     } 
  85. class Program 
  86.     { 
  87. static void Main(string[] args) 
  88.         { 
  89.             Console.Write("**** Welcome to Abstract Factory pattern By DotnetPiper.com *******\n Kinldy enter your car name..."); 
  90.             Client client = new Client(); 
  91.             string carName = Console.ReadLine(); 
  92.             client.CreateCarWithLight(carName); 
  93.             Console.ReadLine(); 
  94.         } 
  95.     } 
  96. }

Run your application now. The following window will appear.
C#
Put the desired car name you would like to know the information about, like Maruti, Tata etc.

Kindly refer to the following window as a result after you put Maruti.
C#


Link to download sample application Abstract Factory Pattern Using C# - Real World Example

    Monday, August 17, 2015

    Aggregation Vs Composition: A Simple Practical Approach

    This article explains the real facts of Aggregation and Composition and I feel it would be a good brain teaser if I come with some actual examples.

    Before proceeding I'd like to share one of the possible situations that you may encounter in your daily need or maybe in an interview. Let's dive into it in a practical way.
    The question is, "What is the difference between composition and aggregation?" In this article I'll provide my understanding of composition and aggregation.
    The following image is fictional and it may be one of the possible scenarios with warrior's fight.

    Aggregation Vs Composition
    Aggregation
    Aggregation means “The act of gathering something together”.
    As inheritance gives us an "is-a" and composition gives us a "part-of" whereas aggregation gives us a "has-a" relationship.
    For example, a mobile “has an” operating system. Aggregation doesn't manage the lifetime of other objects. For an example, mobile uses (has-an) operating system that may be of a different service provider. like Android, iOS and Windows. Here Aggregation theory says that a mobile has an operating system of a specific service provider.
    Aggregation diagram is shown as a UML diagram with unfilled diamond notation as depicted below:
    Aggregation
    The preceding diagram states that a Mobile class may utilize an operating system from a different service provider. A mobile is not directly dependent on an operating system class. Both are independent entities. For example a Samsung is a mobile provider whereas an Android is a Google Product.
    A code snippet shown below that is an OperatingSys object is injecting into the Mobile class at the constructor level. The creation of the OperatingSys class is entirely independent from Mobile Creation. Kindly have a look at the code segment as shown below:

      1: public class Mobile
      2: {
      3:     public OperatingSys objOS;
      4:     public Mobile(OperatingSys objOperatingSys)
      5:     {
      6:         this.objOS = objOperatingSys;
      7:     }
      8:     public string MobileName { get; set; }
      9:     public string OperatingSystem { get; set; }
     10:     public string GetMobileDetails()
     11:     {
     12:         return objOS.OSName() + " Used by " + MobileName;
     13:     }
     14: }
     15: 
     16: public class OperatingSys
     17: {
     18:     public string OS { get; set; }
     19:     public string OSName()
     20:     {
     21:         return "This is Android OS being";
     22:     }
     23: }
     24: 
     25: class Program
     26: {
     27:     static void Main(string[] args)
     28:     {
     29:         OperatingSys objOperatingSys = new OperatingSys();
     30:         Mobile objMobile = new Mobile(objOperatingSys);
     31:         objMobile.MobileName = "Samsung";
     32:         Console.WriteLine(objMobile.GetMobileDetails());
     33:         Console.ReadLine();
     34:     }
     35: }
     36: 
    Composition
    Composition means mixture of ingredients.
    Composition gives us a "part-of" relationship or a mixture of ingredients. Composition is a higher degree of association than aggregation. Composition derives the management of the objects and its lifecycle. In case of composition the lifetime of the owned object is the responsibility of the owner object. Composition is shown on a UML diagram as a filled diamond as depicted below in the screen.
    Composition
    As you can see in the example code snippet below, Mobile manages the lifetime of DisplayScreen, since the DisplayType object depends on the Mobile object. If Mobile is garbage collected, the DisplayType object is also garbage collected.

      1: public class Mobile
      2: {
      3:     public string MobileName { get; set; }
      4:     public string DisplayType { get; set; }
      5: 
      6:     public Mobile()
      7:     {
      8: 
      9:     }
     10: 
     11:     public string GetMobileDetails()
     12:     {
     13:         return this.DisplayType + " Used by " + this.MobileName;
     14:     }
     15: }
     16: 
     17: public class DisplayScreen
     18: {
     19:     public static string ScreenType()
     20:     {
     21:         return "This LED screen display";
     22:     }
     23: }
     24: 
     25: class Program
     26: {
     27:     static void Main(string[] args)
     28:     {
     29:         // OperatingSys objOperatingSys = new OperatingSys();
     30:         Mobile objMobile = new Mobile();
     31:         objMobile.MobileName = "Samsung Galaxy Mobile";
     32:         objMobile.DisplayType = DisplayScreen.ScreenType();
     33:         Console.WriteLine(objMobile.GetMobileDetails());
     34:         Console.ReadLine();
     35:     }
     36: }
     37: 
    Output
    Output

    Note: It might be one of the questions in an interview.

    Tuesday, August 11, 2015

    Extend Sealed Class in C# Using Extension Method - A Simple Approach

    image

    Here we will extend sealed class in C# using extension method.
    Requirement - What is sealed. Can we derive this? If yes, then how we can achieve this?
    Friends this is one of the possible situation which you may confront in your daily need or may be in an interview. Let’s dive it into in practical way.
    Sealed classes are used to restrict the inheritance feature of object oriented programming. Once a class is defined as a sealed class, the class cannot be inherited.
    In C#, the sealed modifier is used to define a class as sealed. In Visual Basic .NET theNotInheritable keyword serves the purpose of sealed. If a class is derived from a sealed class then the compiler throws an error.
    Sealed Methods and Properties

    You can also use the sealed modifier on a method or a property that overrides a virtual method or property in a base class. This enables you to allow classes to derive from your class and prevent other developers that are using your classes from overriding specific virtual methods and properties.
    Here we are not directly extending the functionality using the inheritance feature. We can achieve this with help of an extension method. The following is the code declaration with practical hands on.
    Note: You should have knowledge of extension method in order to implement this.

      1: public sealed class DotnetPiper  
      2: {  
      3:     public DotnetPiper()  
      4:     {  
      5:         Console.WriteLine("D Class Constructor called!");  
      6:     }  
      7:    public void DotnetPiperInstanceMethod()  
      8:     {  
      9:         Console.WriteLine("DotnetPiper is Called!");  
     10:     }  
     11: }  
     12: public class DotnetPiperExtension : DotnetPiper  
     13: {  
     14:   
     15: }  

    As soon as we build our solution we will get the following error:
    Error 1 'OOPS_App.DotnetPiperExtension': cannot derive from sealed type,

    Erro

    I have created an extension class which keeps a method to extend the functionality of sealed class.

      1: public static class DotnetPiperExtension  
      2: {  
      3:     public static string DotnetPiperExtentionMethod(this DotnetPiper objDotnet, string str)  
      4:     {  
      5:         return "Welcome to the World of DotNet....Mr. " + str;  
      6:     }  
      7: } 
    Please have a look at the following image:

    method


    Here I am calling an extension method in main class:

      1: class Program  
      2: {  
      3:     static void Main(string[] args)  
      4:     {  
      5:         DotnetPiper dp = new DotnetPiper();  
      6:         string nameStr = dp.DotnetPiperExtentionMethod("Sachin Kalia");  
      7:         Console.WriteLine(nameStr);  
      8:         Console.ReadLine();   
      9:     }  
     10: }  

    Output:

    CMD


    Complete code for hands on:


     

      1: {  
      2:     public DotnetPiper()  
      3:     {  
      4:         Console.WriteLine("D Class Constructor called!");  
      5:     }  
      6:    public void DotnetPiperInstanceMethod()  
      7:     {  
      8:         Console.WriteLine("DotnetPiper is Called!");  
      9:     }  
     10: }  
     11:   
     12:   
     13: public static class DotnetPiperExtension  
     14: {  
     15:     public static string DotnetPiperExtentionMethod(this DotnetPiper objDotnet, string str)  
     16:     {  
     17:         return "Welcome to the World of DotNet....Mr. " + str;  
     18:     }  
     19: }  
     20:   
     21:   
     22: class Program  
     23: {  
     24:     static void Main(string[] args)  
     25:     {  
     26:         DotnetPiper dp = new DotnetPiper();  
     27:         string nameStr = dp.DotnetPiperExtentionMethod("Sachin Kalia");  
     28:         Console.WriteLine(nameStr);  
     29:         Console.ReadLine();  
     30:   
     31:                 }  
     32:        }  

     


    Note: It might be one of the FAQ in an interview.

    Note: Please share you opinion and advise us for better approach also.I really appreciate you initiation Smile

    To know more MVC and WebApi Kindly go through with these links

    MVC Articles & WCF and WebApi

    Thanks.
    Enjoy coding and reading

    Wednesday, July 29, 2015

    The Open Closed Principle of SOLID

    The Open Closed Principle of SOLID Principle

     

    image

    SOLID principles are like the backbone of OOP, I've gone through with this and obtained a good understanding of this and I thought to share it so that anyone can understand this principle at MAX.
    Here is the list of SOLID principles.

    SRP

    The Single Responsibility Principle

    A class should have one, and only one, reason to change.

    OCP

    The Open Closed Principle

    You should be able to extend a classes behavior, without modifying it.

    LSP

    The Liskov Substitution Principle

    Derived classes must be substitutable for their base classes.

    ISP

    The Interface Segregation Principle

    Make fine grained interfaces that are client specific.

    DIP

    The Dependency Inversion Principle

    Depend on abstractions, not on concretions.

    Today I am hilighting the Open Closed Principle of SOLID.
    Software entities should be open for extension, but closed for modification: Robert Martin
    The preceding statement may be a bit confusiing to understand for those who are not very familiar with these principles.


    Open for Extension: A class should be open for extension only (for example a derived class or subclasses).
    Closed for modification: A class shouldn't be open of modification (for example we should not add code on demand whenever required).


    One thing is sure in all software development, most software changes during its life cycle. So, it requires assurance that developers design software that is stable.
    For example, let's say you are creating a class to represent an Export. The Export class will export the information/dataset to the desired format like a list of employees and related information to a CSV and text format on behalf of the specified provider. The following sample example is for illustrative purposes only:

      1: public enum ProviderName
      2: {
      3:     SQlServer
      4: }
      5: class Export
      6: {
      7:     public bool ExportFileToDesiredFormat(Provider objProvider)
      8:     {
      9:         if (objProvider == ProviderName.SQlServer)
     10:         {
     11:             //Export to CSV,text,.pdf format code segment which depands     on provider
     12:             return true;
     13:         }
     14:         return true;
     15:     }
     16: }
    Now everything looks great. Suppose we come up with one more desired export format. Then at development time it will look like this that is connected with an OLEDB connection:
      1: public enum ProviderName
      2: {
      3:     SQlServer,
      4:     OLEDB,
      5:     Oracle
      6: }
      7: 
      8: class Export
      9: {
     10:     public bool ExportFileToDesiredFormat(string objProvider)
     11:     {
     12:         if (objProvider == ProviderName.SQlServer.ToString())
     13:         {
     14:             //Export to CSV,text,.pdf format code segment which depands on provider
     15:             return true;
     16:         }
     17:         else if (objProvider == ProviderName.OLEDB.ToString())
     18:         {
     19:             //Export to CSV,text,.pdf format code segment which depands on provider
     20:             return true;
     21:         }
     22:         else if (objProvider == ProviderName.Oracle.ToString())
     23:         {
     24:             //Export to CSV,text,.pdf format code segment which depands on provider
     25:             return true;
     26:         }
     27:         else 
     28:         { }
     29:         return true;
     30:     }
     31: }
    Here if you can see from the code above, we are modifying the class Export rather than extending, in other words whenever we add a new export format then we are modifying the existing class that violates the OCP.
    It's time to remember OCP: entities should be open for extension and closed for modification.
    Here is the code segment after considering OCP in mind. The sample example is for illustrative purposes only.

      1: interface IProvider
      2: {
      3:     bool connect(string objProviderName);
      4: }
      5: 
      6: class ExportFileFromSQLProvider : IProvider
      7: {
      8:     public bool connect(string objProviderName)
      9:     {
     10:         //write code on behalf of provider to get connect with SQLProvider and export dataset to desired format such as .csv,.pdf,.text
     11:         return true;
     12:     }
     13: }
     14: 
     15: class ExportFileFromOLEDBProvider : IProvider
     16: {
     17:     public bool connect(string objProviderName)
     18:     {
     19:         //write code on behalf of provide to get connect with OLEDBProvider and export dataset to desired format such as .csv,.pdf,.text
     20:         return true;
     21:     }
     22: }
     23: 
     24: class ExportFileFromOracleProvider : IProvider
     25: {
     26:     public bool connect(string objProviderName)
     27:     {
     28:         //write code on behalf of provide to get connect with OracleProvider and export dataset to desired format such as .csv,.pdf,.text
     29:         return true;
     30:     }
     31: }
     32: 
     33: 
    The main method will look like:
      1: class Program
      2: {
      3:     static void Main(string[] args)
      4:     {
      5:         IProvider objSQLIProvider = new ExportFileFromSQLProvider();
      6:         bool sucess = objSQLIProvider.connect("sqlprovider");
      7:         IProvider objOLEDBIProvider = new ExportFileFromOLEDBProvider();
      8:         bool result = objOLEDBIProvider.connect("OLEDBProvider");
      9:     }
     10: }

    Using this approach we can add as many ProviderName to export a file as needed. Thus the IProvider interface implements the idea of open for extension but closed for modifications.
    It's very easy to understand, especially for those who are not familiar with this principle. Hope you enjoyed this demonstration.


    Enjoy Coding and Have wonderful day ahead Smile


    To know more MVC and WebApi Kindly go through with these links

    MVC Articles & WCF and WebApi

    Thanks.
    Enjoy coding and reading.


    Tuesday, February 24, 2015

    Why Constructor can't be declared Virtually? Why Destructor can't be Overloaded?

    A ChildAction method is an action method thought its accessible from the View only, if you invoked this action via an URL then it prompts

    This is what i found something very interesting about Constructor and Destructor.

    Constructor can't be virtual, because constructor is an entity which initializes V-table(V-table contains address of all the virtual functions of class). So if we declare constructors as virtual then who will initialize V-table for this constructor.

    Destructor can not be overloaded simply becoz we cant provide argument to a destructor and also its going to release the memory when an object goes out of scope.

     

    I hope it will help you somewhere down the line.
    Keep coding and smiling Smile

    To know moew MVC and WebApi Kindly go through with these links

    Learn MVC & WCF and WebAPI

    Friday, October 10, 2014

    Shed Lights on Façade pattern : Just an Interface

    Shed Lights on Façade pattern : Just an Interface

    Dotnetpiper

    Façade means “The face or front”. Facade pattern works in a similar manner as its name means.

    A definition as given below reference from dofactory.

    Ø Provide a unified interface to a set of interfaces in a subsystem. Façade defines a higher-level interface that makes the subsystem easier to use

    Ø Wrap a complicated subsystem with a simpler interface

    IN a layman words “façade provides an interface to interact with sub layers to provide the desired result without interacting with sub layers directly from console”.

    UML class diagram

    clip_image002

    I have used a very basic and daily used real life example to show the case. A Mobile shop.

    Whenever a customer reaches to mobile shop and asks about mobile phone of Brand like Samsung but under the budget (budget could vary) . Please have a look into an image given below:

     

    clip_image004

    As in the image shown above, customer is asking for a phone of brand Samsung under the 15000 INR. He just asked to an interface/ façade layer “shopkeeper”. It doesn’t matter for him what happened behind the scene but he wants the mobile as he desired.

    Hope scenario is cleared.

    Now we jumped into a code segment and understand it practically.

    This is the typical class diagram for the Façade pattern:

    clip_image006

    The classes, interfaces and objects in the above class diagram can be identified as follows:

    Stock, Price, - These are subsystems.

    MobileFacade- Facade class.

    Structural code in C#

    This structural code demonstrates the Facade pattern which provides a simplified and uniform interface to a large subsystem of classes.

    Subsystems Classes Stock and Price code is depicted below:

      1: public class Price
      2:     {
      3:         public string GetMobileNameUnderPrice(string objMobileName,int price)
      4:         {
      5:             switch (price)
      6:             {
      7:                 case 8000:
      8:                     {
      9:                         return objMobileName+ " Trend";                        
     10:                     }
     11:                
     12:                 case 10000:
     13:                     {
     14:                         return objMobileName+ " Ace";
     15:                     }
     16:                 case 15000:
     17:                     {
     18:                         return objMobileName+ " Grand";
     19:                     }
     20:                 case 25000:
     21:                     {
     22:                         return objMobileName+ " S3";
     23:                     }
     24:                 default:
     25:                     return objMobileName+" Guru";
     26:                     break;
     27:             }
     28:         }
     29:     }
     30: 
     31: class Stock
     32:     {
     33:         public bool GetStock()
     34:         {
     35:             return true;
     36:         }
     37:     }
     38: 



    Kindly have a look at the MobileFacade.cs

      1: class MobileFacade
      2:     {
      3:         Stock objStock;
      4:         Price objPrice;
      5:         string strMobileDetails = string.Empty;
      6: 
      7:         public MobileFacade()
      8:         {
      9:             objStock = new Stock();
     10:             objPrice = new Price();
     11:         }
     12: 
     13:         public string GetMobIleDetails(string objMobileName, int price)
     14:         {
     15:             if (objStock.GetStock())
     16:             {
     17:                 strMobileDetails = objPrice.GetMobileNameUnderPrice(objMobileName, price);
     18:                
     19:             }
     20:             return strMobileDetails;
     21:         }
     22:     }
     23: 


      1: /// <summary>
      2:   /// MainApp startup class for Structural
      3:   /// Facade Design Pattern.
      4:   /// </summary>
      5: 
      6: class Program
      7:     {
      8:         static void Main(string[] args)
      9:         {
     10:             MobileFacade objMobileFacade = new MobileFacade();
     11:             Console.WriteLine("Please enter the Amount " );
     12:             int amount = Convert.ToInt16(Console.ReadLine());
     13: 
     14:             string strMobileDetail = objMobileFacade.GetMobIleDetails("Samsung", amount);
     15:            Console.WriteLine(string.Format("The mobile under the price {0} : => is {1}  ",amount, strMobileDetail));
     16:             Console.ReadLine();
     17:         }
     18:     }
     19: 





    If you run you application it asks you to give some amount value so that façade could find out the mobile under the price you have provided:

    clip_image007

    OutPut will be as shown below:

    clip_image008


    Pros:

    · The main advantages of this pattern are that you only interact with an interface to get desired result. What happens behind the scene doesn’t matter.

    · There will be an entry point to each level of layered software.

    Cons

    · A tightly coupled system. Entry point is dependent on sub layers.

    · Façade layers have to create many objects of subclasses internally to get desired output.

    Disclaimer: These all are some finding which I have shared with you.Please touch base with me if you feel any query or suggestion of improvement.


    I wish it will help you utilize both feature at best.

    To learn more about MVC please go to the following link.

    MVC Articles

    Thanks

    Enjoy Coding and Readingclip_image009

    Monday, October 6, 2014

    Shed Some Light On Decorator Pattern in C#

    Decorator Pattern in C#

    Pattern

    "Design Patterns are general, repeatable solutions to common recurring problems in software development."


    A "pattern" has been defined as "an idea that has been useful in one practical context and will probably be useful in others".
    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.
    In this article I'll try to share my thoughts of one of Structural Design Pattern named Decorator.
    Structural Design Patterns are concerned with how classes and objects are combined to form larger structures.
    Let's jump into this and try to swim.


    Definition
    The Gang Of Four (GOF) defines the Decorator pattern as "Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality."

    Closed for Modification and Open for Extension
    One of the main challenges we encounter in development is change. The Closed for Modification and Open for Extension principle says a new functionality can be added by keeping the original code unchanged. To explore more on this kindly visit: The Open Closed Principle of SOLID


    In our applications we occasionally create an object with some basic requirements and later we'd like to add some more functionality to this object dynamically with additional subclasses, in that scenario we use the Decorator Pattern.


    Let's assume we have an object that saves a stream in a Comma Separated Value (CSV) format. Later we need to add more behavior to the same object to save that stream in a bit more secure format like a PDF with a password.
    Here is the class diagram of the Decorator depicted below:


    DecoratorPatt1.jpg
    Participants

    The classes and/or objects participating in this pattern are:

    • Component (Pizza)
      • Defines the interface for objects that can have responsibilities added to them dynamically.
    • ConcreteComponent (ThinCrust,ThikCrust)
      • Defines an object to which additional responsibilities can be attached.
    • Decorator (Decorator)
      • This defines the interface for all the dynamic functionalities that can be added to the reference to a ConcreateComponent.
    • ConcreteDecorator (OnionPizzaDecorator, CheezPizzaDecorator,)
      • Adds responsibilities to the component.

    To understand the decorator pattern let us extend the example being used here. We have a Pizza class as a base class. Later we may add more stuff, like toppings on each Pizza, for example extra cheeze, Onions and Jalapeno with Baby Corn.
    I have chosen a very simple example (Pizza) because most people would be familiar with this. Though there could be the same scenario for other objects like for Ice Cream and Coffee.
    Let us start by creating the component class.


      1: public abstract class Pizza
      2: {
      3: public abstract double GetPrice();
      4: }


    Here is the ConcreateConponent class defines the functionality of the base class Pizza.

      1: class ThikCrust : Pizza
      2: {
      3:     private double p_Price = 250.0;
      4:  
      5:     public override double GetPrice()
      6:     {
      7:         return p_Price;
      8:     }
      9: }
     10:  
     11: class ThinCrust : Pizza
     12: {
     13:     private double p_Price = 200.0;
     14:  
     15:     public override double GetPrice()
     16:     {
     17:         return p_Price;
     18:     }
     19: }


    We are done with the ConcreateConponent and ready for our base object. Now we need to add additional functionality to the base Pizza like the toppings, cheeze and other extra stuff. Let's create a Decorator Class. The main advantages of the decorator is to continue the use of the original class.
    Because there may be many reasons to change the class.



    Conclusion on Change



    So basically we can conclude that whenever changes are required, the possible solutions could be:




    • Change the original class



    • Subclass it and create a subclass



    • Use the Decorator Pattern and still use the original class


    The Decorator class code structure is shown below that extends the base Pizza class.

    Public class Decorator: Pizza
    {
    Pizza basePizza = null;

    protected double p_Price = 0.0;

    protected Decorator(Pizza objPizza)
    {
    basePizza = objPizza;
    }
    public override double GetPrice()
    {
    return p_Price + basePizza.GetPrice();
    }
    }


    First, this class extends the Pizza abstract class. The reason for that is a ThikCrust with a Component will also be a Pizza and thus all the operations possible on a Pizza should also be possible on a decorated Pizza.
    The classes CheezPizzaDecorator and OnionPizzaDecorator extends the Decorator class also and has its own added behavior. You can find this class implementation in the sample application.
    Now our client application can create a combination of these ConcreteComponents with any Decorator. Let's look at the sample code implementation for the client.
    DecoratorPatt2.jpg

    DecoratorPatt2.5.jpg
    The following will be the output:
    DecoratorPatt3.jpg
    It's very easy to understand, especially for those who are not familiar with this pattern. Hope you enjoyed this illustration.
    You can download source code from here.


    Decorator Pattern in C#


    To learn more about MVC please go to the following link.

    MVC Articles

    Thanks.
    Enjoy coding and reading.