Tuesday, December 11, 2007

Generic Decorator Pattern


using System;
using 
System.Collections.Generic;

//Decorator pattern is very powerful pattern which can be used for supplementing the inheritance relationship with 
//composition based relationship. The basic idea is Attaching additional responsibilities to an object dynamically. 
//Decorators provide a flexible alternative to subclassing for extending functionality and it can be implemented 
//on several different ways. 
//This sample program presented here show that it can be done through Generic and Interface. 

//The classes and/or objects participating in this pattern are:
//1. Generic Abstract Decorator
//2. Generic Concrete Decorator
//3. Abstract Component
//4. Concrete Component


namespace Generic.DecoratorPattern
{
    
    // Generic Abstract Decorator 
    
abstract class Decorator<T> : ComputerItem  where T : ComputerItem, new() 
    {
        
protected readonly T computerItem = new T();

        
// Constructor 
        
public Decorator(T computerItem)
        {
            
this.computerItem computerItem;
        
}

        
public override void DisplayReport()
        {
            computerItem.DisplayReport()
;
        
}

    }

    
// Generic Concrete Decorator 
    
class Saleable<T> :  Decorator<T> where T : ComputerItem, new()
    {
        
protected List<string> Buyers = new List<string>();

        
// Constructor 
        
public Saleable(T computerItem) : base(computerItem)
        {
        }

        
public void SaleItem(string name)
        {
            Buyers.Add(name)
;
            
computerItem.NumStocks--;
        
}

        
public void ReturnItem(string name)
        {
            Buyers.Remove(name)
;
            
computerItem.NumStocks++;
        
}

        
public override void DisplayReport()
        {
            
base.DisplayReport();

            foreach 
(string buyer in Buyers)
            {
                Console.WriteLine(
" Buyer: " + buyer);
            
}
        }
    }

    
interface IComputerItem
    {
        
void DisplayReport();
    
}

    
// Abstract Component 
    
abstract class ComputerItem : IComputerItem
    {
        
private string brand;

        public string 
Brand
        {
            
get return brand}
            
set { brand = value; }
        }

        
private string type;

        public string 
Type
        {
            
get return type}
            
set { type = value; }
        }

        
private int numStocks;

        public int 
NumStocks
        {
            
get return numStocks}
            
set { numStocks = value; }
        }

        
public abstract void DisplayReport();
    
}

    
// Concrete Component 
    
class Desktop : ComputerItem
    {
        
public Desktop()
        { }

        
public Desktop(string brand, string type, int numStocks)
        {
            
this.Brand brand;
            this
.Type type;
            this
.NumStocks numStocks;
        
}

        
public override void DisplayReport()
        {
            Console.WriteLine(
"\n----- Desktop ----- ");
            
Console.WriteLine(" Brand: {0}", Brand);
            
Console.WriteLine(" Type: {0}", Type);
            
Console.WriteLine(" # Stocks: {0}", NumStocks);
        
}
    }

    
// Concrete Component 
    
class Laptop : ComputerItem
    {
        
public Laptop()
        { }

        
public Laptop(string brand, string type, int numStocks)
        {
            
this.Brand brand;
            this
.Type type;
            this
.NumStocks numStocks;
        
}

        
public override void DisplayReport()
        {
            Console.WriteLine(
"\n----- Laptop ----- ");
            
Console.WriteLine(" Brand: {0}", Brand);
            
Console.WriteLine(" Type: {0}", Type);
            
Console.WriteLine(" # Stocks: {0}", NumStocks);
        
}
    }

    
class Program
    {
        
static void Main()
        {
            
// Create desktop 
            
Desktop desktop = new Desktop("HPP""XM600"32);
            
desktop.DisplayReport();

            
// Create laptop 
            
Laptop laptop = new Laptop("ASUSS""F3MAP0"9);
            
laptop.DisplayReport();

            
Console.WriteLine("\nMaking laptop saleable:");

            
Saleable<Laptop> saleLaptop = new Saleable<Laptop>(laptop);
            
saleLaptop.SaleItem("Customer #1");
            
saleLaptop.SaleItem("Customer #2");
            
saleLaptop.SaleItem("Customer #3");

            
saleLaptop.DisplayReport();

            
Console.Read();
        
}
    }
}

2 comments:

adi said...

well done.

probably a gentle introduction with diagrams will be very helpful.

Excalibur said...

Very2 nice decorator

Indonesia To Blog -Top Site
SEO - search engine submission and optimisation