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

No comments:

Post a Comment