[設計模式練習]使用觀察者模式將邏輯層與展現層分離

[設計模式練習]使用觀察者模式將邏輯層與展現層分離

程式畫面如下

pic1

將兩個數相乘之後輸出結果

省略錯誤處理的部份=.=

原先的程式


using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace TestObserver
{    
    public partial class Form1 : Form 
    {        
        public Form1()
        {
            InitializeComponent();
            
        }
        private void button1_Click(object sender, EventArgs e)
        {
            string num1 = textBox1.Text;
            string num2 = textBox2.Text;
            textBox3.Text = Convert.ToString(int.Parse(num1) * int.Parse(num2));

        }        
    }
}

首先將邏輯層抽離出來


using System.Collections.Generic;
using System.Text;

namespace TestObserver
{
    
    /// <summary>
    /// 邏輯層(乘法)
    /// </summary>
    public class Multiply 
    {
        private string num1;//乘數一
        private string num2;//承數二
        public Multiply() { }
        public void SetNum1(string innum1)
        {
            num1 = innum1;
        }
        public void SetNum2(string innum2)
        {
            num2 = innum2;
        }
        public string GetNum1()
        {
            return num1;
        }
        public string GetNum2()
        {
            return num2;
        }
        public string GetResult()//取得相乘後結果
        {
            return Convert.ToString(int.Parse(num1) * int.Parse(num2));
        }        

    }
    
}

修改主程式


using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace TestObserver
{    
    public partial class Form1 : Form 
    {        
        public Form1()
        {
            InitializeComponent();
            
        }
        private void button1_Click(object sender, EventArgs e)
        {
            Multiply m1 = new Multiply();
            m1.SetNum1(textBox1.Text);
            m1.SetNum2(textBox2.Text);
            textBox3.Text = m1.GetResult();
        }        
    }
}

加入觀察者與被觀察者


    /// 抽象界面:被觀察者
    /// </summary>
    public abstract class Subject
    {
        //要通知的觀察者
        protected List<IObserver> observers = new List<IObserver>();
        /// <summary>
        /// 加入觀察者.
        /// </summary>
        /// <param name="observer">The observer.</param>
        public void Attach(IObserver observer)
        {
            observers.Add(observer);
        }
        /// <summary>
        /// 移除觀察者.
        /// </summary>
        /// <param name="observer">The observer.</param>
        public void Detach(IObserver observer)
        {
            observers.Remove(observer);
        }
        /// <summary>
        /// 發出訊息通知觀察者做下一步動作.
        /// </summary>
        public abstract void Notify();
        
    }
    /// <summary>
    /// 觀察者介面
    /// </summary>
    public interface IObserver
    {
        void updated(Multiply s1);
    }

修改原來邏輯層


    /// 被觀查者:邏輯層(乘法)
    /// </summary>
    public class Multiply : Subject
    {
        private string num1;//乘數一
        private string num2;//承數二
        public Multiply() { }
        public void SetNum1(string innum1)
        {
            num1 = innum1;
        }
        public void SetNum2(string innum2)
        {
            num2 = innum2;
        }
        public string GetNum1()
        {
            return num1;
        }
        public string GetNum2()
        {
            return num2;
        }
        public string GetResult()//取得相乘後結果
        {
            return Convert.ToString(int.Parse(num1) * int.Parse(num2));
        }
        /// <summary>
        /// 發出訊息通知觀察者做下一步動作.
        /// 即GUI介面
        /// </summary>
        public override void Notify()
        {
            foreach (IObserver tmpobserver in observers)
            {
                tmpobserver.updated(this);
            }
        }

    }

再次修改主程式


using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace TestObserver
{
    //觀查者:GUI界面(window form)
    public partial class Form1 : Form ,IObserver
    {
        Multiply m1 = new Multiply();
        public Form1()
        {
            InitializeComponent();
            //將GUI界面加入觀查者
            m1.Attach(this);
        }
        private void button1_Click(object sender, EventArgs e)
        {
            /* 被觀察者邏輯層發出通知
             * 更新觀查者GUI界面的內容
             * 
             * */
            m1.Notify();
        }
        public void updated(Multiply s1)
        {
            s1.SetNum1(textBox1.Text);
            s1.SetNum2(textBox2.Text);
            textBox3.Text = m1.GetResult();
        }
    }
}

輸出結果

pic2