Showing posts with label Observer Design Pattern. Show all posts
Showing posts with label Observer Design Pattern. Show all posts

Sunday, November 10, 2013

Observer design pattern from Real World

Hello
Observer design pattern well described here: WIKI: Observer pattern

I wish give some real example.

So, example...
My example is: GUI for creating controls + share information between:

My UI is very simple: 2 buttons + text box:

Add listener button, which create UserControl and subscribe it
Remove listener: remove UserControl and detach it
Text box: when it updates, each UserControl get informed about new text

UserControl:
Lable: show Subject status
TextBox: can be updated, so updated text goes to Subject and from Subject to each Observer:

And, if i wish talk with pictures:

Start app:

Add listener:


Add 1 more listener:

Now, main UI set text ("hello") in its textbox, so each listener get it ("hello") and show in own lable:

And, 1-st listener can set its text ("mama") in its textbox:
and we see, "mama" is updated for each listener


Now, main UI set new text ("papa") in its textbox, so each listener get it ("papa") and show in own lable:

Code

Solution:

IObserver.cs:
namespace ObserverFormDP
{
    public interface IObserver
    {
        void StateUpdate();
    }
}

ISubject.cs:
using System;

namespace ObserverFormDP
{
    public interface ISubject
    {
        String State { get; set; }
        void Attach(IObserver obsever);
        void Detach(IObserver obsever);
        void Notify();
    }
}

Subject.cs:
using System.Collections.Generic;

namespace ObserverFormDP
{
    public class Subject : ISubject
    {
        private string _state;
        private List<IObserver> _attachedObservers;

        public Subject()
        {
            _attachedObservers = new List<IObserver>();
        }

        public void Attach(IObserver obsever)
        {
            _attachedObservers.Add(obsever);
        }

        public void Detach(IObserver obsever)
        {
            _attachedObservers.Remove(obsever);
        }

        public void Notify()
        {
            foreach (IObserver o in _attachedObservers)
            {
                o.StateUpdate();
            }
        }

        public string State
        {
            get
            {
                return _state;
            }
            set
            {
                _state = value;
                Notify();
            }
        }
    }
}

UserControl1:
using System.Windows.Forms;

namespace ObserverFormDP
{
    public partial class UserControl1 : UserControl, IObserver
    {
        private ISubject _subject;

        public UserControl1(ISubject subject)
        {
            InitializeComponent();

            _subject = subject;
        }

        public void StateUpdate()
        {
            label1.Text = _subject.State;
        }

        private void textBox1_TextChanged(object sender, System.EventArgs e)
        {
            _subject.State = textBox1.Text;
        }
    }
}

Form1:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace ObserverFormDP
{
    public partial class Form1 : Form
    {
        List<IObserver> _observers;
        ISubject _subject;

        public Form1()
        {
            InitializeComponent();
            _observers = new List<IObserver>();
            _subject = new Subject();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            UserControl1 uc1 = new UserControl1(_subject);
            _observers.Add(uc1);
            _subject.Attach(uc1);
            uc1.Location = new Point(_observers.Count * 110, 20);
            Controls.Add(uc1);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (_observers.Count == 0) return;
            IObserver o = _observers[_observers.Count - 1];
            Controls.Remove(o as UserControl);
            _observers.Remove(o);
            _subject.Attach(o);
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            _subject.State = textBox1.Text;
        }
    }
}

Thats all

Thanks,
Efim