Pixytech

Lead Architect  •  Full Stack Engineer

Category: Architecture

  • .Net Universe

    .NET Universe Poster

    A visual map of the entire .NET ecosystem — frameworks, tools, languages, runtimes and libraries — all in one poster. The original PDF version is no longer available for direct download but the poster content is captured above.

  • .Net Cryptography (Encryption / Decryption)

    There are two techniques for encrypting data: symmetric encryption (secret key encryption) and asymmetric encryption (public key encryption.)

    Symmetric Encryption

    Symmetric encryption is the oldest and best-known technique. A secret key, which can be a number, a word, or just a string of random letters, is applied to the text of a message to change the content in a particular way. This might be as simple as shifting each letter by a number of places in the alphabet. As long as both sender and recipient know the secret key, they can encrypt and decrypt all messages that use this key.

    Asymmetric Encryption

    The problem with secret keys is exchanging them over the Internet or a large network while preventing them from falling into the wrong hands. Anyone who knows the secret key can decrypt the message. One answer is asymmetric encryption, in which there are two related keys–a key pair. A public key is made freely available to anyone who might want to send you a message. A second, private key is kept secret, so that only you know it.

    Any message (text, binary files, or documents) that are encrypted by using the public key can only be decrypted by applying the same algorithm, but by using the matching private key. Any message that is encrypted by using the private key can only be decrypted by using the matching public key.

    This means that you do not have to worry about passing public keys over the Internet (the keys are supposed to be public). A problem with asymmetric encryption, however, is that it is slower than symmetric encryption. It requires far more processing power to both encrypt and decrypt the content of the message

     

    Lets see how both the techniques can be implemented using C#.Net 4.0

    //The CryptoBase class represents the base class for both kind of techniques. the code is mentioned below

     
    
    public abstract class CryptoBase:IDisposable
    {
    public CryptoBase(IDisposable provider)
    {
    this.Provider = provider;
    }
    
    protected IDisposable Provider { get; private set; }
    
    /// <summary>
    /// Encryption the source stream and save result to target stream
    /// </summary>
    /// <param name="source"></param>
    /// <param name="target"></param>
    public abstract void Encrypt(System.IO.Stream source, System.IO.Stream target);
    
    /// <summary>
    /// Decrypt the source stream and save result to target stream
    /// </summary>
    /// <param name="source"></param>
    /// <param name="target"></param>
    public abstract void Decrypt(System.IO.Stream source, System.IO.Stream target);
    
    protected abstract void OnDisposeProvider();
    
    /// <summary>
    /// Copy the source stream to target stream and transform the bytes (using function deligate) before copying onto target stream
    /// </summary>
    /// <param name="source">Source stream</param>
    /// <param name="target">Target stream</param>
    /// <param name="BytesProcessor">Function deligate to process the data beforw it get copied to target stream.</param>
    protected void CopyStream(Stream source, Stream target, Func<byte[], byte[]> BytesProcessor)
    {
    const int bufSize = 1024;
    byte[] buf = new byte[bufSize];
    int bytesRead = 0;
    while ((bytesRead = source.Read(buf, 0, bufSize)) > 0)
    {
    //extract the actual buffer using bytesRead
    byte[] buffactual = new byte[bytesRead];
    
    //Copt the data to buffer
    Array.Copy(buf, buffactual, bytesRead);
    
    //Call the bytes processor to process the bytes before we write it to target
    byte[] processed = BytesProcessor(buffactual);
    
    //Write the new data to target.
    target.Write(processed, 0, processed.Length);
    }
    }
    
    /// <summary>
    /// Copy the source tream to target stream.
    /// </summary>
    /// <param name="source">Source stream</param>
    /// <param name="target">Target stream</param>
    protected void CopyStream(Stream source, Stream target)
    {
    const int bufSize = 1024;
    byte[] buf = new byte[bufSize];
    int bytesRead = 0;
    while ((bytesRead = source.Read(buf, 0, bufSize)) > 0)
    target.Write(buf, 0, bytesRead);
    }
    
    private bool isDisposing = false;
    ~CryptoBase()
    {
    this.Dispose();
    }
    
    private void Dispose()
    {
    if (!isDisposing && Provider != null)
    {
    OnDisposeProvider();
    isDisposing = true;
    Provider.Dispose();
    Provider = null;
    }
    }
    
    void IDisposable.Dispose()
    {
    this.Dispose();
    }
    }

    Now lets see the Symmetric implementation based on RijndaelManaged provider

    /// <summary>
    /// Symmetric encryption/decryption class based on RijndaelManaged provider
    /// </summary>
    public sealed class Symmetric : CryptoBase
    {
    
    private readonly byte[] passcode;
    private readonly byte[] vector;
    
    /// <summary>
    /// Initilize the Symmetric Encryption from Vector, PassCode and Salt
    /// </summary>
    /// <param name="Vector">Randomly generated 16 bit array (16 means - 128 bit AES encryption)</param>
    /// <param name="PassCode">Random passcode bytes. passcode size should be from (5 to 15)*8 bytes</param>
    /// <param name="Salt"></param>
    public Symmetric(byte[] Vector, byte[] PassCode,string Salt):base(new RijndaelManaged())
    {
    MD5CryptoServiceProvider md5Crypt = new MD5CryptoServiceProvider();
    
    //Construct the derived password, hash name should be SHA1 or MD5
    PasswordDeriveBytes password = new PasswordDeriveBytes(PassCode, md5Crypt.ComputeHash(UnicodeEncoding.ASCII.GetBytes(Salt)), "SHA1", 2);
    //C# provides 4 different symmetric crypto algorithms:
    //RijndaelManaged, DESCryptoServiceProvider, RC2CryptoServiceProvider, and TripleDESCryptoServiceProvider.
    
    //Rijndael is the same as AES (Advanced Encryption Standard - approved by NSA, very strong)
    //but with more choice about the size of your key.
    
    SymmetricAlgorithm symmetricProvider = base.Provider as RijndaelManaged;
    symmetricProvider.Mode = CipherMode.CBC;
    
    //Set the passcode and vector
    passcode = password.GetBytes(32);
    vector = Vector;
    }
    public override void Encrypt(Stream source, Stream target)
    {
    SymmetricAlgorithm symmetricProvider = base.Provider as RijndaelManaged;
    
    //Create encryptor from passcode and vector
    using (ICryptoTransform CryptoTransformer = symmetricProvider.CreateEncryptor(passcode, vector))
    {
    //Encrypt the stream
    using (CryptoStream cryptostream = new CryptoStream(target, CryptoTransformer, CryptoStreamMode.Write))
    {
    base.CopyStream(source, cryptostream);
    }
    }
    
    }
    
    public override void Decrypt(Stream source, Stream target)
    {
    SymmetricAlgorithm symmetricProvider = base.Provider as RijndaelManaged;
    
    //Create decryptor from passcode and vector
    using (ICryptoTransform CryptoTransformer = symmetricProvider.CreateDecryptor(passcode, vector))
    {
    //Decrypt the stream
    using (CryptoStream cryptostream = new CryptoStream(source, CryptoTransformer, CryptoStreamMode.Read))
    {
    CopyStream(cryptostream, target);
    }
    }
    }
    
    protected override void OnDisposeProvider()
    {
    SymmetricAlgorithm symmetricProvider = base.Provider as RijndaelManaged;
    symmetricProvider.Clear();
    }
    }

    and the asymmetric implementation as well

     
    /// <summary>
    /// Asymmetric (RSA) encryption/decryption class
    /// </summary>
    internal sealed class Asymmetric : CryptoBase
    {
    
    /* Note: the RSACryptoServiceProvider reverses the order of encrypted bytes
    * after encryption and before decryption. If you do not require compatibility
    * with Microsoft Cryptographic API (CAPI) and/or other vendors
    * Set CAPICompatibility = False;
    */
    
    private readonly bool CAPICompatibility = true;
    
    /// <summary>
    /// Create the provider from RSACryptoService Provider
    /// </summary>
    /// <param name="provider"></param>
    public Asymmetric(RSACryptoServiceProvider provider):base(provider)
    {
    
    }
    
    /// <summary>
    /// Encrypt the data using RSACryptoServiceProvider
    /// </summary>
    /// <param name="bytes"></param>
    /// <returns></returns>
    private byte[] Encrypt(byte[] bytes)
    {
    RSACryptoServiceProvider Provider = base.Provider as RSACryptoServiceProvider;
    
    int keySize = Provider.KeySize / 8;
    
    // The hash function in use by the .NET RSACryptoServiceProvider here is SHA1
    int maxLength = (keySize) - 2 - (2 * SHA1.Create().ComputeHash(bytes).Length);
    
    int dataLength = bytes.Length;
    //Compute the iterations based on data length
    int iterations = dataLength / maxLength;
    List<byte> result = new List<byte>();
    //loop through data and encrypt the bytes
    for (int i = 0; i <= iterations; i++)
    {
    byte[] tempBytes = new byte[(dataLength - maxLength * i > maxLength) ? maxLength : dataLength - maxLength * i];
    Buffer.BlockCopy(bytes, maxLength * i, tempBytes, 0, tempBytes.Length);
    byte[] encryptedBytes = Provider.Encrypt(tempBytes, false);
    //The microsoft crypto api reverse the bytes after encryption
    //if CAPICompatibility is required the reverse the data
    if (CAPICompatibility)
    Array.Reverse(encryptedBytes);
    result.AddRange(encryptedBytes);
    }
    //return the encrypted data
    return result.ToArray();
    }
    
    /// <summary>
    /// Decrypt the byte array based on RSACryptoServiceProvider
    /// </summary>
    /// <param name="bytes"></param>
    /// <returns></returns>
    private byte[] Decrypt(byte[] bytes)
    {
    RSACryptoServiceProvider Provider = base.Provider as RSACryptoServiceProvider;
    
    //Compute the key size
    int keySize = Provider.KeySize / 8;
    
    int maxLength = keySize;
    
    int dataLength = bytes.Length;
    //Compute the iterations based on data length
    int iterations = dataLength / maxLength;
    
    List<byte> result = new List<byte>();
    for (int i = 0; i <= iterations; i++)
    {
    byte[] tempBytes = new byte[(dataLength - maxLength * i > maxLength) ? maxLength : dataLength - maxLength * i];
    if (tempBytes.Length > 0)
    {
    Buffer.BlockCopy(bytes, maxLength * i, tempBytes, 0, tempBytes.Length);
    //The microsoft crypto api requires the reversed bytes before decryption
    //if CAPICompatibility is set then reverse the data
    if (CAPICompatibility)
    Array.Reverse(tempBytes);
    //Decrypt the data
    byte[] encryptedBytes = Provider.Decrypt(tempBytes, false);
    result.AddRange(encryptedBytes);
    }
    }
    //return the decrypted data
    return result.ToArray();
    }
    public override void Encrypt(Stream source, Stream target)
    {
    //Call the Copy Stream function and pass the refrence to Encrypt function as byte processor
    //The byte processor will be called before writting final data to output stream
    CopyStream(source, target, Encrypt);
    }
    
    public override void Decrypt(Stream source, Stream target)
    {
    //Call the Copy Stream function and pass the refrence to Decrypt function as byte processor
    //The byte processor will be called before writting final data to output stream
    CopyStream(source, target, Decrypt);
    }
    
    protected override void OnDisposeProvider()
    {
    RSACryptoServiceProvider symmetricProvider = base.Provider as RSACryptoServiceProvider;
    symmetricProvider.Clear();
    }
    
    }

    And at last the usage function will look like

    class Program
    {
    private static Random random = new Random();
    
    static void Main(string[] args)
    {
    //Asymmetric Encryption/Decryption usage
    //Get the certificate
    
    X509Certificate2 certificate = null;// = Get the certificate from store (Left for ideveloper/implementor )
    
    //User the private key to decrypt the data
    using (CryptoBase asymmetric = new Asymmetric((RSACryptoServiceProvider)certificate.PrivateKey))
    {
    
    //asymmetric.Decrypt(source ,target);
    
    }
    
    //User the public key to encrypt the data
    using (CryptoBase asymmetric = new Asymmetric((RSACryptoServiceProvider)certificate.PublicKey.Key))
    {
    //asymmetric.Encrypt(source ,target);
    }
    //Symmetric Encryption/Decryption usage
    //Get the certificate
    
    byte[] vector = GenerateRandomBytes(16);
    byte[] passcode = GenerateRandomBytes(10);
    string salt = "ChooseSalt";
    
    //User the private key to decrypt the data
    using (CryptoBase asymmetric = new Symmetric(vector,passcode,salt))
    {
    
    //asymmetric.Decrypt(source ,target);
    
    }
    
    //User the public key to encrypt the data
    using (CryptoBase asymmetric = new Symmetric(vector, passcode, salt))
    {
    //asymmetric.Encrypt(source ,target);
    }
    
    }
    
    public static byte[] GenerateRandomBytes(int Size)
    {
    byte[] buffer = new byte[Size];
    random.NextBytes(buffer);
    return buffer;
    }
    }

    The initialization of certificate from data store is not implemented in above sample.

    If you have huge data and Asymmetric encryption is doesn’t meet you performance requirements, you could mix both the techniques. For eg. Decrypt the Symmetric keys using Asymmetric technique and write it on header of the data. Decrypt the rest of data segment with fast Symmetric technique.To make it more stronger you might develop custom decryption technique which decrypt most of data with symmetric but also decrypt some segment of data with Asymmetric technique. Use certificates with key size of 1024 bit or higher for more security.

  • Behavioural Design Patterns

    Behavioral design patterns are design patterns that identify common communication patterns between objects and realize these patterns. By doing so, these patterns increase flexibility in carrying out this communication.

    Behavioural Patterns

    • Mediator:- Defines simplified communication between classes.
    • Memento:-Capture and restore an object’s internal state.
    • Interpreter: – A way to include language elements in a program.
    • Iterator:-Sequentially access the elements of a collection.
    • Chain of Resp: – A way of passing a request between a chain of objects.
    • Command:-Encapsulate a command request as an object.
    • State:-Alter an object’s behavior when its state changes.
    • Strategy:-Encapsulates an algorithm inside a class.
    • Observer: – A way of notifying change to a number of classes.
    • Template Method:- Defer the exact steps of an algorithm to a subclass.
    • Visitor:- Defines a new operation to a class without change.

    Many a times in projects communication between components are complex. Due to this the logic between the components becomes very complex. Mediator pattern helps the objects to communicate in a disassociated manner, which leads to minimizing complexity.Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.
    Example : The classes and/or objects participating in this pattern are:

    • Mediator (IChatroom)
      • defines an interface for communicating with Colleague objects
    • ConcreteMediator (Chatroom)
      • implements cooperative behavior by coordinating Colleague objects
      • knows and maintains its colleagues
    • Colleague classes (Participant)
      • each Colleague class knows its Mediator object
      • each colleague communicates with its mediator whenever it would have otherwise communicated with another colleague
    interface IChatroom
    {
        void Send(string message, Colleague participant);
    
    }
    class Chatroom : IChatroom
    {
        Colleague colleague1;
        Colleague colleague2;
    
        public Colleague Colleague1
        {
            set { colleague1 = value; }
        }
    
        public Colleague Colleague2
        {
            set { colleague2 = value; }
        }
    
        public void Send(string message, Colleague colleague)
        {
            if (colleague == colleague1)
            {
                colleague2.Notify(message);
            }
            else
            {
                colleague1.Notify(message);
            }
        }
    }
    abstract class Participant
    {
        protected IChatroom mediator;
        string name;
        // Constructor
        public Participant(string Name, IChatroom mediator)
        {
          this.mediator = mediator;
          this.name = Name;
        }
        public string Name
        {
            get { return this.name; }
        }
      }
    
    class Colleague:Participant
    {
    
        public Colleague(string Name, IChatroom mediator) : base(Name, mediator) { }
    
        public void Send(string message)
        {
          mediator.Send(message, this);
        }
    
        public void Notify(string message)
        {
          Console.WriteLine( this.Name + " gets message: "  + message);
        }
    
    }
    //Application
    Chatroom room = new Chatroom();
    Colleague c1 = new Colleague("Rajneesh Noonia", room);
    Colleague c2 = new Colleague("Robert", room);
    room.Colleague1 = c1;
    room.Colleague2 = c2;
    c1.Send("How are you?");
    c2.Send("Fine, thanks");

    Memento pattern is the way to capture objects internal state with out violating encapsulation. Memento pattern helps us to store a snapshot which can be reverted at any moment of time by the object. Let’s understand what it means in practical sense. Consider ‘Memento practical example’, it shows a customer screen. Let’s say if the user starts editing a customer record and he makes some changes. Later he feels that he has done something wrong and he wants to revert back to the original data. This is where memento comes in to play. It will help us store a copy of data and in case the user presses cancel the object restores to its original state.The memento pattern is used by two objects: the originator and a caretaker. The originator is some object that has an internal state. The caretaker is going to do something to the originator, but wants to be able to undo the change. The caretaker first asks the originator for a memento object. Then it does whatever operation (or sequence of operations) it was going to do. To roll back to the state before the operations, it returns the memento object to the originator. The memento object itself is an opaque object (one which the caretaker cannot, or should not, change). When using this pattern, care should be taken if the originator may change other objects or resources – the memento pattern operates on a single object.
    Example :

    // The 'Originator' class
    class Originator
    {
        private string _state;
        // Property
        public string State
        {
            get { return _state; }
            set
            {
                _state = value;
                Console.WriteLine("State = " + _state);
            }
        }
    
        // Creates memento
        public Memento CreateMemento()
        {
            return (new Memento(_state));
        }
        // Restores original state
        public void SetMemento(Memento memento)
        {
            Console.WriteLine("Restoring state...");
            State = memento.State;
        }
    }
    
    // The 'Memento' class
    class Memento
    {
        private string _state;
        // Constructor
        public Memento(string state)
        {
            this._state = state;
        }
        // Gets or sets state
        public string State
        {
            get { return _state; }
        }
    }
    
    // The 'Caretaker' class
    class Caretaker
    {
        private Memento _memento;
        // Gets or sets memento
        public Memento Memento
        {
            set { _memento = value; }
            get { return _memento; }
        }
    }
    //Application
    
    Originator o = new Originator();
    o.State = "On";
    // Store internal state
    Caretaker c = new Caretaker();
    c.Memento = o.CreateMemento();
    // Continue changing originator
    o.State = "Off";
    // Restore saved state
    o.SetMemento(c.Memento);

    Interpreter pattern allows us to interpret grammar in to code solutions. Ok, what does that mean ?. Grammars are mapped to classes to arrive to a solution. For instance 7 – 2 can be mapped to ‘Minus’ class. In one line interpreter pattern gives us the solution of how to write an interpreter which can read a grammar and execute the same in the code. The interpreter pattern specifies how to evaluate sentences in a language. The basic idea is to have a class for each symbol (terminal or nonterminal) in a specialized computer language. The syntax tree of a sentence in the language is an instance of the composite pattern and is used to evaluate (interpret) the sentence.
    Example :

    interface IExpression
    {
        int Interpret(Dictionary variables);
    }
    
    class Number : IExpression
    {
        public int number;
        public Number(int number) { this.number = number; }
        public int Interpret(Dictionary<string, int> variables) { return number; }
    }
    
    abstract class BasicOperation : IExpression
    {
        IExpression leftOperator, rightOperator;
    
        protected BasicOperation() { }
    
        public BasicOperation(IExpression left, IExpression right)
        {
            leftOperator = left;
            rightOperator = right;
        }
    
        public int Interpret(Dictionary<string, int> variables)
        {
            return Execute(leftOperator.Interpret(variables), rightOperator.Interpret(variables));
        }
    
        abstract protected int Execute(int left, int right);
    }
    
    class Plus : BasicOperation
    {
        public Plus(IExpression left, IExpression right) : base(left, right) { }
    
        protected override int Execute(int left, int right)
        {
            return left + right;
        }
    }
    
    class Minus : BasicOperation
    {
        public Minus(IExpression left, IExpression right) : base(left, right) { }
    
        protected override int Execute(int left, int right)
        {
            return left - right;
        }
    }
    
    class Variable : IExpression
    {
        private string name;
    
        public Variable(string name) { this.name = name; }
    
        public int Interpret(Dictionary<string, int> variables)
        {
            return variables[name];
        }
    }
    
    class Evaluator
    {
        private IExpression syntaxTree;
    
        public Evaluator(string expression)
        {
            Stack<IExpression> stack = new Stack<IExpression>();
            foreach (string token in expression.Split(' '))
            {
                if (token.Equals("+"))
                    stack.Push(new Plus(stack.Pop(), stack.Pop()));
                else if (token.Equals("-"))
                    stack.Push(new Minus(stack.Pop(), stack.Pop()));
                else
                    stack.Push(new Variable(token));
            }
            syntaxTree = stack.Pop();
        }
    
        public int Evaluate(Dictionary<string, int> context)
        {
            return syntaxTree.Interpret(context);
        }
    }
    
    //Application
    
    Evaluator evaluator = new Evaluator("w x z - +");
    Dictionary<string, int> values = new Dictionary<string,int>();
    values.Add("w", 5);
    values.Add("x", 8);
    values.Add("z", 15);
    Console.WriteLine(evaluator.Evaluate(values));

    Iterator pattern allows sequential access of elements with out exposing the inside code. Let’s understand what it means. Let’s say you have a collection of records which you want to browse sequentially and also maintain the current place which recordset is browsed, then the answer is iterator pattern. It’s the most common and unknowingly used pattern. Whenever you use a ‘foreach’ (It allows us to loop through a collection sequentially) loop you are already using iterator pattern to some extent.
    Example :

    public class Employee{   
        private int m_nID;
        private string m_strName;
        public Employee(int nID, string strName){
            m_nID = nID;
            m_strName = strName;
        }
        public int EmployeeID{get{return this.m_nID;}}
        public string EmployeeName{get{return this.m_strName;}}
    }
    public class EnumerateEmployee: IEnumerator
    {
        private int m_nPosition;
        private ArrayList m_ArrEmployee = new ArrayList();
        public EnumerateEmployee(){
            m_nPosition = -1;
            m_ArrEmployee.Add(new Employee(1,"Kamsa"));
            m_ArrEmployee.Add(new Employee(2,"Rama"));
            m_ArrEmployee.Add(new Employee(3,"Sita"));
            m_ArrEmployee.Add(new Employee(4,"Gopala"));
        }
        public bool MoveNext(){
            bool b_return = false;
            ++m_nPosition;
            if(m_nPosition < m_ArrEmployee.Count)
            b_return = true;
            return b_return;
        }
        public object Current {get{return m_ArrEmployee[m_nPosition];}}
        public void Reset(){m_nPosition = -1;}
    }
    
    //Application
    
    string strName;
    int nID;
    EmployeeList objEmpList = new EmployeeList();
    IEnumerator objEnumEmp = objEmpList.GetEnumerator();
    while(objEnumEmp.MoveNext())
    {
        Employee objEmployee = (Employee)objEnumEmp.Current; 
        nID = objEmployee.EmployeeID; strName = objEmployee.EmployeeName;
    }
    

    Chain of responsibility is used when we have series of processing which will be handled by a series of handler logic. There are situations when a request is handled by series of handlers. So the request is taken up by the first handler, he either can handle part of it or can not, once done he passes to the next handler down the chain. This goes on until the proper handler takes it up and completes the processing. Example :

    class Purchase
    {
        public int Number { get; set; }
        public double Amount { get; set; }
        public string Description { get; set; }
        public Purchase(int Number, double Amount, string Description)
        {
            this.Number = Number;
            this.Amount = Amount;
            this.Description = Description;
        }
    }
    
    abstract class Approver
    {
        protected Approver(Approver Successor)
        {
            this.Successor = Successor;
        }
        protected Approver Successor { get; private set; }
        public abstract void ProcessRequest(Purchase purchase);
    }
    
    //Various Approvers (request handlers)
    class Director : Approver
    {
        public Director(Approver Successor):base(Successor){}
        
        public override void ProcessRequest(Purchase purchase)
        {
            if (purchase.Amount < 10000.0)
            {
                Console.WriteLine("{0} approved request# {1}",this.GetType().Name, purchase.Number);
            }
            else if (Successor != null)
            {
                Successor.ProcessRequest(purchase);
            }
        }
    }
    
    class VicePresident : Approver
    {
        public VicePresident(Approver Successor) : base(Successor) { }
        public override void ProcessRequest(Purchase purchase)
        {
            if (purchase.Amount < 25000.0)
            {
                Console.WriteLine("{0} approved request# {1}",this.GetType().Name, purchase.Number);
            }
            else if (Successor != null)
            {
                Successor.ProcessRequest(purchase);
            }
        }
    }
    
    class President : Approver
    {
        public President(Approver Successor) : base(Successor) { }
        public override void ProcessRequest(Purchase purchase)
        {
            if (purchase.Amount < 100000.0)
            {
                Console.WriteLine("{0} approved request# {1}",this.GetType().Name, purchase.Number);
            }
            else
            {
                Console.WriteLine("Request# {0} requires an executive meeting!",purchase.Number);
            }
        }
    }
    
    //Application
    // Setup Chain of Responsibility
    
    Approver director = new Director(null);
    Approver vicePresident = new VicePresident(director);
    Approver president = new President(vicePresident);
    
    // Generate and process purchase requests
    Purchase p = new Purchase(2034, 350.00, "Assets");
    director.ProcessRequest(p);
    
    p = new Purchase(2035, 32590.10, "Project X");
    director.ProcessRequest(p);
    
    p = new Purchase(2036, 122100.00, "Project Y");
    director.ProcessRequest(p);
    

    Command pattern allows a request to exist as an object. The command pattern is a design pattern in which an object is used to represent and encapsulate all the information needed to call a method at a later time. This information includes the method name, the object that owns the method and values for the method parameters.

    Three terms always associated with the command pattern are client, invoker and receiver. The client instantiates the command object and provides the information required to call the method at a later time. The invoker decides when the method should be called. The receiver is an instance of the class that contains the method’s code.

    Using command objects makes it easier to construct general components that need to delegate, sequence or execute method calls at a time of their choosing without the need to know the owner of the method or the method parameters.
    Example :

    State pattern allows an object to change its behavior depending on the current values of the object. Consider the ‘State pattern example’. It’s an example of a bulb operation. If the state of the bulb is off and you press the switch the bulb will turn off. If the state of bulb is on and you press the switch the bulb will be off. So in short depending on the state the behavior changes. Example :

    Strategy pattern are algorithms inside a class which can be interchanged depending on the class used. This pattern is useful when you want to decide on runtime which algorithm to be used.
    Example :

    Observer pattern helps us to communicate between parent class and its associated or dependent classes. There are two important concepts in observer pattern ‘Subject’ and ‘Observers’. The subject sends notifications while observers receive notifications if they are registered with the subject. Example :

    In template pattern we have an abstract class which acts as a skeleton for its inherited classes. The inherited classes get the shared functionality. The inherited classes take the shared functionality and add enhancements to the existing functionality. In word or power point how we take templates and then prepare our own custom presentation using the base. Template classes works on the same fundamental.
    Example :

    Visitor pattern allows us to change the class structure with out changing the actual class. Its way of separating the logic and algorithm from the current data structure. Due to this you can add new logic to the current data structure with out altering the structure. Second you can alter the structure with out touching the logic. Example :

    *Visitor and strategy look very much similar as they deal with encapsulating complex logic from data. We can say visitor is more general form of strategy.

  • Structural Design Patterns

    Structural design patterns are design patterns that ease the design by identifying a simple way to realize relationships between entities.

    In this tutorial you will learn about Structural Patterns – Adapter, Bridge, Composite, Decorator, Facade, Flyweight and Proxy.

    Structural Patterns

    • Adapter:-Match interfaces of different classes.
    • Bridge:-Separates an object’s abstraction from its implementation.
    • Composite:-A tree structure of simple and composite objects.
    • Decorator:-Add responsibilities to objects dynamically.
    • Facade:-A single class that represents an entire subsystem.
    • Flyweight:-A fine-grained instance used for efficient sharing.
    • Proxy:-An object representing another object.

    Many times two classes are incompatible because of incompatible interfaces. Adapter pattern helps us to wrap a class around the existing class and make the classes compatible with each other. There are two way of implementing adapter pattern one is by using aggregation (this is termed as the object adapter pattern) and the other inheritance (this is termed as the class adapter pattern).

    Example :

    // Existing class.. this may be your legacy code or third party code
    class Adaptee
    {
        // validates the email
        public bool IsEmail(string email)
        {
            return System.Text.RegularExpressions.Regex.IsMatch(email, @"email validation reg expression here");
        }
    }
    
    // Required standard implementing through interface
    interface ITarget
    {
        // Rough estimate required
        bool ValidateEmail(string email);
    }
    // Implementing the required standard via Adaptee
    class Adapter : Adaptee, ITarget
    {
        public bool ValidateEmail(string email)
        {
            return IsEmail(email);
        }
    }
    //Application
    
      // Showing the Adaptee in standalone mode
            Adaptee first = new Adaptee();
            bool valid = first.IsEmail("rajneeshnoonia@gmail.com"));
    
            // What the client really wants
           // Note that  Adaptee (3rd party or legacy code) is not used here,and Adapter is wraper for
           // Adaptee accessed via standard interface ITarget.If in future we found better adaptee we would not be require
          // to change client code.
            ITarget second = new Adapter();
           valid = second.ValidateEmail("rajneeshnoonia@gmail.com"));

    Bridge pattern helps to decouple abstraction from implementation. With this if the implementation changes it does not affect abstraction and vice versa. The switch is the abstraction and the electronic equipments are the implementations. The switch can be applied to any electronic equipment, so the switch is an abstract thinking while the equipments are implementations.

    interface IDraw
    {
        void DrawCircle(double x, double y, double radius);
    }
    
    class DrawGDI : IDraw
    {
        public void DrawCircle(double x, double y, double radius)
        {
           //Draw Circle using GDI API
        }
    }
    class DrawDirectX : IDraw
    {
        public void DrawCircle(double x, double y, double radius)
        {
            //Draw Circle using DirectX API
        }
    
    }
    
    interface Shape
    {
        void Draw();
    }
    class Circle:Shape
    {
        private double x, y, radius;
        private IDraw display;
        public Circle(double x, double y, double radius, IDraw display)
        {
            this.x = x;
            this.y = y;
            this.radius = radius;
            this.display = display;
        }
    
        public void Draw()
        {
            this.display.DrawCircle(this.x, this.y, this.radius);
        }
    }
    
    //Application
    List<Shape> shapes = new List<Shape>();
    shapes.Add(new Circle(10,10,20,new DrawGDI()));
    shapes.Add(new Circle(40,10,20,new DrawDirectX()));
    foreach (Shape shape in shapes)
    {
        shape.Draw();
    }

    Composite pattern allows treating different objects in a similar fashion. In order to treat objects in a uniformed manner we need to inherit them from a common interface.The Composite Design pattern allows a client object to treat both single components and collections of components identically. 

    Example :

    interface IGraphics
    {
        void Draw();
    }
    
    class Circle : IGraphics
    {
        public void Draw()
        {
            //Draw Circle
        }
    }
    
    class Composite : IGraphics
    {
        private List<IGraphics> childs = new List<IGraphics>();
        public Composite(IEnumerable<IGraphics> composite)
        {
            childs.AddRange(composite);
        }
        public void Draw()
        {
            //Draw composite graphics
            foreach (IGraphics child in this.childs)
            {
                child.Draw();
            }
        }
    }
    
    //Application
    //Build tree of objects
    Composite CGraphics1 = new Composite(new IGraphics[]{new Circle(),new Circle()});
    Composite CGraphics2 = new Composite(new IGraphics[]{CGraphics1,new Circle(),new Circle()});
    Composite CompositeGraphic = new Composite(new IGraphics[]{CGraphics2,new Circle()});
    CompositeGraphic.Draw();
     

    Decorator pattern is a design pattern that allows new/additional behaviour to be added to an existing object dynamically.
    The decorator pattern can be used to make it possible to extend (decorate) the functionality of a certain object at runtime, independently of other instances of the same class, provided some groundwork is done at design time. This is achieved by designing a new decorator class that wraps the original class.

    Decorator Patterns belong to the Structural Pattern category and it’s role is in providing a way of attaching new behavior to the object at run time. The object is unaware of the new behavior and this pattern is a good candidate for enhancing legacy applications. Decorator Pattern provides a way of adding functionality to an existing class without using inheritance.

    Example :

    Let us assume we are maintaining an application for a car manufacturing company. When the application was created, the company manufactured only one type of car – the normal car.

    interface ICar
    {
        string Description {get;}
        double Price{ get;}
     }
    class NormalCar:ICar
    {
        public string  Description
        {
            get { return "Normal Car"; }
        }
    
        public double  Price
        {
    	    get { return 2000f; }
        }
    }

    Over several years, the customers demanded that they be provided with different options to customize the car. The management decided to provide two different options. One to customize the paint based on the customer needs and the other an option to fit the car with a turbo charged engine.

    To enhance the application to support customizations, we could extend the Normal Car’s functionality by creating derived classes such as CustomPaintCar or TurboEngineCar. In future, if the management decides to provide more options, it would be practically impossible to create classes that can be used for different combinations.

    By using the Decorator pattern, we could combine different options at run time. First, we need to create a Decorator base class.

    abstract class CarDecorator:ICar
    {
        private ICar car;
        public CarDecorator(ICar car)
        {
            this.car=car;
        }
        public virtual string  Description
        {
    	    get { return this.car.Description; }
        }
    
        public virtual double  Price
        {
    	    get { return this.car.Price; }
        }
    }
    
    class CustomPaintCar :CarDecorator
    {
        public CustomPaintCar(ICar car):base(car){}
        public override string  Description
        {
    	    get
    	    {
    		     return base.Description + " with custom paint";
    	    }
        }
        public override double  Price
        {
    	    get
    	    {
    		     return base.Price + 1000f;
    	    }
        }
    }
    class TurboEngineCar :CarDecorator
    {
        public TurboEngineCar(ICar car):base(car){}
        public override string  Description
        {
    	    get
    	    {
    		     return base.Description + " with turbo engine";
    	    }
        }
        public override double  Price
        {
    	    get
    	    {
    		     return base.Price + 2000f;
    	    }
        }
    }
    //Application
    //Normal or basic car with
    ICar basicCar = new NormalCar();
    //exiting car = normal car + custom paint
    ICar exitingCar = new CustomPaintCar(new NormalCar());
    //amazing car = normal car + custom paint + turbo engine
    ICar amazingCar = new TurboEngineCar(new CustomPaintCar(new NormalCar()));

    Facade pattern sits on the top of group of subsystems and allows them to communicate in a unified manner.

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

    Facade   (MortgageApplication)

    • knows which subsystem classes are responsible for a request.
    • delegates client requests to appropriate subsystem objects.

    Subsystem classes   (Bank, Credit, Loan)

    • implement subsystem functionality.
    • handle work assigned by the Facade object.
    • have no knowledge of the facade and keep no reference to it.

    Example :

      // The 'Subsystem ClassA' class
      class SubSystemOne
      {
        public void MethodOne()
        {
    
        }
      }
      // The 'Subsystem ClassB' class
      class SubSystemTwo
      {
        public void MethodTwo()
        {
    
        }
      }
      // The 'Subsystem ClassC' class
      class SubSystemThree
      {
        public void MethodThree()
        {
    
        }
      }
    
      // The 'Subsystem ClassD' class
      class SubSystemFour
      {
        public void MethodFour()
        {
    
        }
      }
      // The 'Facade' class
      class Facade
      {
        private SubSystemOne _one;
        private SubSystemTwo _two;
        private SubSystemThree _three;
        private SubSystemFour _four;
        public Facade()
        {
          _one = new SubSystemOne();
          _two = new SubSystemTwo();
          _three = new SubSystemThree();
          _four = new SubSystemFour();
        }
        public void MethodA()
        {
          _one.MethodOne();
          _two.MethodTwo();
          _four.MethodFour();
        }
        public void MethodB()
        {
          _two.MethodTwo();
          _three.MethodThree();
        }
      }
    
    //Application
    Facade facade = new Facade();
    facade.MethodA();
    facade.MethodB();

    Fly weight pattern is useful where we need to create many objects and all these objects share some kind of common data. Consider ‘Objects and common data’. We need to print visiting card for all employees in the organization. So we have two parts of data one is the variable data i.e. the employee name and the other is static data i.e. address. We can minimize memory by just keeping one copy of the static data and referencing the same data in all objects of variable data. So we create different copies of variable data, but reference the same copy of static data. With this we can optimally use the memory.

    Example : Support you have a project to create employee ID card.The variable data here will be employee name and employee ID where as the common or shared data here will be Company address.

    //abstract address
    public abstract class Address
    {
        public abstract string Address1 { get; set; }
    }
    //concreate address
    internal class CompanyAddress : Address
    {
        string address;
        public override string Address1
        {
            get { return address; }
            set { address = value; }
        }
    }
    //singleton pattern to have one instance of address
    public sealed partial class Application
    {
        public static Address CompAddress { get; private set; }
        static Application()
        {
            CompAddress = new CompanyAddress();
            CompAddress.Address1 = "Company Address";
        }
    
    }
    //abstract IDCard
    public abstract class IDCard
    {
        public string Name { get; set; }
        public int EmpCode { get; set; }
        public abstract Address CompanyAddress { get;}
    }
    
    //Concreate implementation of IDCard
    public class EmployeeIDCard : IDCard
    {
        public override Address CompanyAddress
        {
            get
            {
                return Application.CompAddress;
            }
        }
    }
    
    //Application
    List cards = new List();
    
    for (int empCode = 1; empCode <= 2000; empCode++)
    {
        cards.Add(new EmployeeIDCard { EmpCode=empCode,Name = String.Format("Emp{0} Name",empCode)});
    }

    Proxy pattern fundamentally is a class functioning as in interface which points towards the actual class which has data. This actual data can be a huge image or an object data which very large and can not be duplicated. So you can create multiple proxies and point towards the huge memory consuming object and perform operations. This avoids duplication of the object and thus saving memory. Proxies are references which points towards the actual object. The advantages of using proxy are security and avoiding duplicating objects which are of huge sizes. Rather than shipping the code we can ship the proxy, thus avoiding the need of installing the actual code at the client side. With only the proxy at the client end we ensure more security. Second point is when we have huge objects it can be very memory consuming to move to those large objects in a network or some other domain. So rather than moving those large objects we just move the proxy which leads to better performance.
    Example :
    A proxy, in its most general form, is a class functioning as an interface to something else. The proxy could interface to anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate.

    interface IImage
    {
        void Display();
    }
    
    class RealImage : IImage
    {
        public RealImage(string fileName)
        {
            FileName = fileName;
            LoadFromFile();
        }
    
        private void LoadFromFile()
        {
            Console.WriteLine("Loading " + FileName);
        }
    
        public String FileName { get; private set; }
    
        public void Display()
        {
            Console.WriteLine("Displaying " + FileName);
        }
    }
    
    class ProxyImage : IImage
    {
        public ProxyImage(string fileName)
        {
            FileName = fileName;
        }
    
        public String FileName { get; private set; }
    
        private IImage image;
    
        public void Display()
        {
            if (image == null)
                image = new RealImage(FileName);
            image.Display();
        }
    }
    //Application
    IImage image = new ProxyImage("HiRes_Image");
    for (int i = 0; i < 10; i++)
        image.Display();