Friday, June 7, 2013

Observer Design Patterns in c#

Observer: Allows a single object to notify many dependent objects that its state has changed.

class Program
    {
        static void Main(string[] args)
        {
            DummyProduct product = new DummyProduct();

            // We have four shops wanting to keep updated price set by product owner
            Shop shop1 = new Shop("Shop 1");
            Shop shop2 = new Shop("Shop 2");

            Shop shop3 = new Shop("Shop 3");
            Shop shop4 = new Shop("Shop 4");

            //Lets use WAY_1 for first two shops
            product.Attach(shop1);
            product.Attach(shop2);

            //Lets use WAY_2 for other two shops
            product.Attach2(shop3);
            product.Attach2(shop4);

            //Now lets try changing the products price, this should update the shops automatically
            product.ChangePrice(23.0f);

            //Now shop2 and shop 4 are not interested in new prices so they unsubscribe
            product.Detach(shop2);
            product.Detach2(shop4);

            //Now lets try changing the products price again
            product.ChangePrice(26.0f);

            Console.Read();
        }
    }
    interface IObserver
    {
        void Update(float price);
    }
    class Shop : IObserver
    {
        string name;
        float price = 0.0f;

        public Shop(string name)
        {
            this.name = name;
        }

        #region IObserver Members

        public void Update(float price)
        {
            this.price = price;
            Console.WriteLine(@"Price at {0} is now {1}", name, price);
        }

        #endregion
    }
    abstract class ASubject
    {
        ArrayList list = new ArrayList();

        public delegate void StatusUpdate(float price);
        public event StatusUpdate OnStatusUpdate = null;

        public void Attach(Shop product)
        {
            list.Add(product);
        }
        public void Detach(Shop product)
        {
            list.Remove(product);
        }
        public void Attach2(Shop product)
        {
            OnStatusUpdate += new StatusUpdate(product.Update);
        }
        public void Detach2(Shop product)
        {
            OnStatusUpdate -= new StatusUpdate(product.Update);
        }
        public void Notify(float price)
        {
            foreach (Shop p in list)
            {
                p.Update(price);
            }
            if (OnStatusUpdate != null)
                OnStatusUpdate(price);
        }

    }
    class DummyProduct : ASubject
    {
        public void ChangePrice(float price)
        {
            Notify(price);
        }

    }

Observer Design Patterns in c#

*The Observer pattern in which registered investors are notified every time a stock changes value.

class Program
    {
        static void Main(string[] args)
        {
            IBM ibm = new IBM("IBM", 1202.00);
            ibm.Attach(new Investor("Sorros"));
            ibm.Attach(new Investor("Berkshire"));

            ibm.Price = 120.00;
            ibm.Price = 121.00;
            ibm.Price = 120.44;

            Console.ReadKey();
        }
    }

    interface IInvestor
    {
        void Update(Stock stock);
    }
    abstract class Stock
    {
        //An abstract class cannot be instantiated. 
        //The purpose of an abstract class is to provide "a common definition of a base class" that multiple derived classes can share. 
        private string _symbol;
        private double _price;
        private List<IInvestor> _investors = new List<IInvestor>();

        public Stock(string symbol, double price)
        {
            _symbol = symbol;
            _price = price;
        }
        public void Attach(IInvestor investor)
        {
            _investors.Add(investor);
        }
        public void Detach(IInvestor investor)
        {
            _investors.Remove(investor);
        }
        public void Notity()
        {
            foreach (IInvestor investor in _investors)
            {
                investor.Update(this);
            }
        }
        public double Price
        {
            get { return _price; }
            set
            {
                if (_price != value)
                {
                    _price = value;
                    Notity();
                }
            }
        }
        public string Symbol
        {
            get { return _symbol; }
        }
    }

    class IBM : Stock
    {
        public IBM(string symbol, double price) : base(symbol, price) { }
    }
    class Investor : IInvestor
    {
        private string _name;
        private Stock _stock;

        public Investor(string name)
        {
            this._name = name;
        }

        internal Stock Stock
        {
            get { return _stock; }
            set { _stock = value; }
        }

        public void Update(Stock stock)
        {
            Console.WriteLine("Notified {0} of {1}'s " + "Change to {2:C}", _name, stock.Symbol, stock.Price);
        }
    }

Observer Design Patterns - Behavioral Patterns in C#

Observer: Allows a single object to notify many dependent objects that its state has changed.

* Define a one-to-many dependency between objects so that when one object changes state,

     *   all its dependents are notified and updated automatically.

class Program
    {
        static void Main(string[] args)
        {
            ConcreteSubject s = new ConcreteSubject();

            s.Attach(new ConcreteObserver(s, "x"));
            s.Attach(new ConcreteObserver(s, "y"));
            s.Attach(new ConcreteObserver(s, "z"));

            s.SubjectState = "abc";
            s.Notify();
            Console.ReadKey();
        }
    }

    abstract class Observer
    {
        public abstract void Update();
    }
    abstract class Subject
    {
        private List<Observer> _observer = new List<Observer>();
        public void Attach(Observer observer)
        {
            _observer.Add(observer);
        }
        public void Detach(Observer observer)
        {
            _observer.Remove(observer);
        }
        public void Notify()
        {
            foreach (Observer o in _observer)
            {
                o.Update();
            }
        }
    }

    class ConcreteObserver : Observer
    {
        private string _name;
        private string _observerState;
        private ConcreteSubject _subject;

        public ConcreteObserver(ConcreteSubject subject, string name)
        {
            _subject = subject;
            _name = name;
        }

        public ConcreteSubject Subject
        {
            get { return _subject; }
            set { _subject = value; }
        }

        public string ObserverState
        {
            get { return _observerState; }
            set { _observerState = value; }
        }

        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }


        public override void Update()
        {
            _observerState = _subject.SubjectState;
            Console.WriteLine("Observer {0}'s new state is {1}", _name, _observerState);
        }
    }
    class ConcreteSubject : Subject
    {
        private string _subjectState;

        public string SubjectState
        {
            get { return _subjectState; }
            set { _subjectState = value; }
        }

    }

Memento Design Patterns - Behavioral Patterns in C#

Memento: Allows you to save the state of an object externally from that object.

* Without violating encapsulation, capture and externalize an object's internal state so that the 

object can be restored to this state later.


 class Program
    {
        static void Main(string[] args)
        {
            Originator org = new Originator();
            org.State = "ON";

            //Store internal state
            Caretaker c = new Caretaker();
            c.Memento = org.CreateMemento();

            //Continue changing originator
            org.State = "OFF";

            //Restore saved state
            org.SetMemento(c.Memento);

            Console.ReadKey();
        }
    }
    class Originator
    {
        private string _state;

        public string State
        {
            get { return _state; }
            set
            {
                _state = value;
                Console.WriteLine("State = " + _state);
            }
        }
        //Creates memento
        public Memento CreateMemento()
        {
            return (new Memento(_state));
        }
        public void SetMemento(Memento memento)
        {
            Console.WriteLine("Restoring state..");
            State = memento.State;
        }
    }
    class Memento
    {
        private string _state;
        public Memento(string state)
        {
            this._state = state;
        }
        public string State
        {
            get { return _state; }
        }
    }
    class Caretaker
    {
        private Memento _memento;
        public Memento Memento
        {
            set { _memento = value; }
            get { return _memento; }
        }

    }

Mediator Design Patterns in c#

What is mediator pattern?

According to the GOF the "Mediator Pattern defines an object that encapsulates how a set of objects interact."
Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it let's you vary their interaction independently.
When to use?

Consider a situation where we have many classes encapsulating specific logic inside them (like invoicing, inventory management, payroll).
     * 
     * Chat application using Mediator Pattern

Let's build a small chat-based application.

Note:

This will not be a real-time chat application.
***** A real chat application requires sockets or other network-based programming along with a Mediator pattern.

     * ***A Mediator Pattern or any other design pattern we have already discussed are not rules, and its not even mandatory that it be used in every application. 
     * Try to understand your problem first and then see which design pattern satisfies your requirements.

class Program
    {
        static void Main(string[] args)
        {
            ClsAbstractMediator objMediator = new ClsMediator();
            ClsUser userA = new ClsMobileUser("userA");
            ClsUser userB = new ClsMobileUser("userB");
            ClsUser userC = new ClsDesktopUser("userC");
            ClsUser userD = new ClsDesktopUser("userD");
            objMediator.AddUser(userA);
            objMediator.AddUser(userB);
            objMediator.AddUser(userC);
            objMediator.AddUser(userD);
            userA.Send("userB", "Hi userB, can you help me to understand mediator pattern");
            userB.Send("userA", "sorry man, even i m trying to understand the same.Try to consult userC");
            userA.Send("userB", "OK\n");
            userA.Send("userC", "hey userC can you help me.");
            userC.Send("userA", "sorry bro, m busy right now, working on an article,will ping in some time ;)");
            userC.Send("userA", "As usual :P");
        }
    }
    public abstract class ClsUser
    {
        internal string userName { get; set; }
        internal ClsAbstractMediator objMediator;
        public ClsUser(string userName)
        {
            this.userName = userName;
        }
        public abstract void Send(string toUser, string message);
        public abstract void Receive(string fromUser, string message);
    }
    public abstract class ClsAbstractMediator
    {
        public abstract void AddUser(clsUser user);
        public abstract void RemoveUser(string userName);
        public abstract void SendMessage(string fromUser, string toUser, string message);
    }
    public class ClsDesktopUser : ClsUser
    {
        public override void Send(string toUser, string message)
        {
            objMediator.SendMessage(toUser, this.userName, message);
        }

        public override void Receive(string fromUser, string message)
        {
            Console.WriteLine(this.userName + ":" + message);
        }
    }


    public class ClsDesktopUser : ClsUser
    {
        public override void Receive(string fromUser, string message)
        {
            Console.WriteLine(this.userName + ":" + message);
        }
        public override void Send(string toUser, string message)
        {
            objMediator.SendMessage(toUser, this.userName, message);
        }
    }
    public class ClsMobileUser : ClsUser
    {
        public override void Receive(string fromUser, string message)
        {
            Console.WriteLine(this.userName + ":" + message);
        }
        public override void Send(string toUser, string message)
        {
            objMediator.SendMessage(this.userName, toUser, message);
        }
    }

Mediator Design Patterns in c#

Mediator: The mediator pattern encapsulate the interaction between a set of objects.

class Program
    {
        static void Main(string[] args)
        {
            FacebookGroupMediator m = new FacebookGroupMediator();
            
            Fan fan1 = new Fan(m, "Fan 1");
            FanB fan2 = new FanB(m, "Fan 2");
            Fan fan3 = new Fan(m, "Fan 3");

            fan1.Send("i like this group");
            fan2.Send("yes i also like this group");

            m.Block(fan3.Receive);

            fan1.Send("Do you agree that this is the best group");
            fan2.Send("Yes i agree");
            m.Unblock(fan3.Receive);
            fan1.Send("Thanks all");

            Console.ReadKey();
        }
    }

    class FacebookGroupMediator
    {
        public delegate void CallBack(string message, string from);
        CallBack respond;
        public void SignOn(CallBack method)
        {
            respond += method;
        }
        public void Block(CallBack method)
        {
            respond -= method;
        }
        public void Unblock(CallBack method)
        {
            respond += method;
        }
        //Send is implemented as a broadcast
        public void Send(string message, string from)
        {
            respond(message, from);
        }
    }
    class Fan
    {
        FacebookGroupMediator mediator;
        protected string name;

        public Fan(FacebookGroupMediator mediator, string name)
        {
            this.mediator = mediator;
            mediator.SignOn(Receive);
            this.name = name;
        }
        public virtual void Receive(string message, string from)
        {
            Console.WriteLine(name + " received from " + from + ": " + message);
        }
        public void Send(string message)
        {
            Console.WriteLine("Send (From " + name + "): " + message);
            mediator.Send(message, name);
        }
    }
    class FanB : Fan
    {
        public FanB(FacebookGroupMediator mediator, string name) : base(mediator, name) { }
        //Does not get copies of own messages
        public override void Receive(string message, string from)
        {
            if (!string.Equals(from, name))
                Console.WriteLine(name + " received from " + from + ": " + message);
        }

    }

Mediator Design Patterns (Behavioral Patterns) in C#

Mediator: The mediator pattern encapsulate the interaction between a set of objects.

class Program
    {
        static void Main(string[] args)
        {
            IBM ibm = new IBM("IBM", 150.00);
            ibm.Attach(new Investor("aaa"));
            ibm.Attach(new Investor("bbb"));

            //Fluctuating prices will notify investors
            ibm.Price = 150.00;
            ibm.Price = 152.00;
            ibm.Price = 130.00;

            Console.ReadKey();
        }
    }

    interface IInvestor
    {
        void Update(Stock stock);
    }

    class Investor : IInvestor
    {
        private string _name;
        private Stock _stock;

        public Investor(string name)
        {
            _name = name;
        }
        public void Update(Stock stock)
        {
            Console.WriteLine("Notified {0} of {1} 's change to {2:c}", _name, stock.Symbol, stock.Price);
        }
        public Stock Stock
        {
            get { return _stock; }
            set { _stock = value; }
        }
    }

    abstract class Stock
    {
        private string _symbol;
        private double _price;
        private List<IInvestor> _investors = new List<IInvestor>();

        public Stock(string symbol, double price)
        {
            this._symbol = symbol;
            this._price = price;
        }
        public void Attach(IInvestor investor)
        {
            _investors.Add(investor);
        }
        public void Detach(IInvestor investor)
        {
            _investors.Remove(investor);
        }
        public void Notify()
        {
            foreach (IInvestor investor in _investors)
            {
                investor.Update(this);
            }
        }
        public double Price
        {
            get { return _price; }
            set
            {
                if (_price != value)
                {
                    _price = value;
                    Notify();
                }
            }
        }
        public string Symbol
        {
            get { return _symbol; }
        }
    }

    class IBM : Stock
    {
        public IBM(string symbol, double price) : base(symbol, price) { }

    }