1. 程式人生 > >Design Pattern - Observer(C#)

Design Pattern - Observer(C#)

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!

               

Definition

Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

Participants

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

  • Subject  (Stock) 
    • Knows its observers. Any number of Observer objects may observe a subject
    •   
    • Provides an interface for attaching and detaching Observer objects.
    •  
  •  
  • ConcreteSubject  (IBM) 
    • Stores state of interest to ConcreteObserver
    •   
    • Sends a notification to its observers when its state changes
    •  
  •  
  • Observer  (IInvestor) 
    • Defines an updating interface for objects that should be notified of changes in a subject.
    •  
  •  
  • ConcreteObserver  (Investor) 
    • Maintains a reference to a ConcreteSubject object
    •   
    • Stores state that should stay consistent with the subject's
    •   
    • Implements the Observer updating interface to keep its state consistent with the subject's
    •  

Sample Code in C#


This structural code demonstrates the Observer pattern in which registered objects are notified of and updated with a state change.

// --------------------------------------------------------------------------------------------------------------------// <copyright company="Chimomo's Company" file="Program.cs">// Respect the work.// </copyright>// <summary>// Structural Observer Design Pattern.// </summary>// --------------------------------------------------------------------------------------------------------------------namespace CSharpLearning{    using System;    using System.Collections.Generic;    /// <summary>    /// Startup class for Structural Observer Design Pattern.    /// </summary>    internal static class Program    {        #region Methods        /// <summary>        /// Entry point into console application.        /// </summary>        private static void Main()        {            // Configure Observer pattern            var s = new ConcreteSubject();            s.Attach(new ConcreteObserver(s, "X"));            s.Attach(new ConcreteObserver(s, "Y"));            s.Attach(new ConcreteObserver(s, "Z"));            // Change subject and notify observers            s.SubjectState = "ABC";            s.Notify();        }        #endregion    }    /// <summary>    /// The 'Subject' abstract class    /// </summary>    internal abstract class Subject    {        #region Fields        /// <summary>        /// The observers.        /// </summary>        private List<Observer> observers = new List<Observer>();        #endregion        #region Public Methods and Operators        /// <summary>        /// The attach.        /// </summary>        /// <param name="observer">        /// The observer.        /// </param>        public void Attach(Observer observer)        {            this.observers.Add(observer);        }        /// <summary>        /// The detach.        /// </summary>        /// <param name="observer">        /// The observer.        /// </param>        public void Detach(Observer observer)        {            this.observers.Remove(observer);        }        /// <summary>        /// The notify.        /// </summary>        public void Notify()        {            foreach (Observer o in this.observers)            {                o.Update();            }        }        #endregion    }    /// <summary>    /// The 'ConcreteSubject' class    /// </summary>    internal class ConcreteSubject : Subject    {        // Gets or sets subject state        #region Public Properties        /// <summary>        /// Gets or sets the subject state.        /// </summary>        public string SubjectState { get; set; }        #endregion    }    /// <summary>    /// The 'Observer' abstract class    /// </summary>    internal abstract class Observer    {        #region Public Methods and Operators        /// <summary>        /// The update.        /// </summary>        public abstract void Update();        #endregion    }    /// <summary>    /// The 'ConcreteObserver' class    /// </summary>    internal class ConcreteObserver : Observer    {        #region Fields        /// <summary>        /// The name.        /// </summary>        private string name;        /// <summary>        /// The observer state.        /// </summary>        private string observerState;        /// <summary>        /// The subject.        /// </summary>        private ConcreteSubject subject;        #endregion        // Constructor        #region Constructors and Destructors        /// <summary>        /// Initializes a new instance of the <see cref="ConcreteObserver"/> class.        /// </summary>        /// <param name="subject">        /// The subject.        /// </param>        /// <param name="name">        /// The name.        /// </param>        public ConcreteObserver(ConcreteSubject subject, string name)        {            this.subject = subject;            this.name = name;        }        #endregion        #region Public Properties        /// <summary>        /// Gets or sets the subject.        /// </summary>        public ConcreteSubject Subject        {            get            {                return this.subject;            }            set            {                this.subject = value;            }        }        #endregion        #region Public Methods and Operators        /// <summary>        /// The update.        /// </summary>        public override void Update()        {            this.observerState = this.subject.SubjectState;            Console.WriteLine("Observer {0}'s new state is {1}", this.name, this.observerState);        }        #endregion    }}// Output:/*Observer X's new state is ABCObserver Y's new state is ABCObserver Z's new state is ABC*/

 


This real-world code demonstrates the Observer pattern in which registered investors are notified every time a stock changes value.

// --------------------------------------------------------------------------------------------------------------------// <copyright company="Chimomo's Company" file="Program.cs">//  Respect the work.// </copyright>// <summary>//  Real-World Observer Design Pattern.// </summary>// --------------------------------------------------------------------------------------------------------------------namespace CSharpLearning{    using System;    using System.Collections.Generic;    /// <summary>    /// The 'Observer' interface    /// </summary>    internal interface IInvestor    {        #region Public Methods and Operators        /// <summary>        /// The update.        /// </summary>        /// <param name="stock">        /// The stock.        /// </param>        void Update(Stock stock);        #endregion    }    /// <summary>    /// Startup class for Real-World Observer Design Pattern.    /// </summary>    internal static class Program    {        #region Methods        /// <summary>        /// Entry point into console application.        /// </summary>        private static void Main()        {            // Create IBM stock and attach investors            var ibm = new IBM("IBM", 120.00);            ibm.Attach(new Investor("Sorros"));            ibm.Attach(new Investor("Berkshire"));            // Fluctuating prices will notify investors            ibm.Price = 120.10;            ibm.Price = 121.00;            ibm.Price = 120.50;            ibm.Price = 120.75;        }        #endregion    }    /// <summary>    /// The 'Subject' abstract class    /// </summary>    internal abstract class Stock    {        #region Fields        /// <summary>        /// The investors.        /// </summary>        private List<IInvestor> investors = new List<IInvestor>();        /// <summary>        /// The price.        /// </summary>        private double price;        #endregion        // Constructor        #region Constructors and Destructors        /// <summary>        /// Initializes a new instance of the <see cref="Stock"/> class.        /// </summary>        /// <param name="symbol">        /// The symbol.        /// </param>        /// <param name="price">        /// The price.        /// </param>        protected Stock(string symbol, double price)        {            this.Symbol = symbol;            this.price = price;        }        #endregion        #region Public Properties        /// <summary>        /// Gets or sets the price.        /// </summary>        public double Price        {            get            {                return this.price;            }            set            {                if (this.price != value)                {                    this.price = value;                    this.Notify();                }            }        }        /// <summary>        /// Gets the symbol.        /// </summary>        public string Symbol { get; private set; }        #endregion        #region Public Methods and Operators        /// <summary>        /// The attach.        /// </summary>        /// <param name="investor">        /// The investor.        /// </param>        public void Attach(IInvestor investor)        {            this.investors.Add(investor);        }        /// <summary>        /// The detach.        /// </summary>        /// <param name="investor">        /// The investor.        /// </param>        public void Detach(IInvestor investor)        {            this.investors.Remove(investor);        }        /// <summary>        /// The notify.        /// </summary>        public void Notify()        {            foreach (IInvestor investor in this.investors)            {                investor.Update(this);            }            Console.WriteLine(string.Empty);        }        #endregion        // Gets or sets the price    }    /// <summary>    /// The 'ConcreteSubject' class    /// </summary>    internal class IBM : Stock    {        // Constructor        #region Constructors and Destructors        /// <summary>        /// Initializes a new instance of the <see cref="IBM"/> class.        /// </summary>        /// <param name="symbol">        /// The symbol.        /// </param>        /// <param name="price">        /// The price.        /// </param>        public IBM(string symbol, double price)            : base(symbol, price)        {        }        #endregion    }    /// <summary>    /// The 'ConcreteObserver' class    /// </summary>    internal class Investor : IInvestor    {        #region Fields        /// <summary>        /// The name.        /// </summary>        private string name;        #endregion        // Constructor        #region Constructors and Destructors        /// <summary>        /// Initializes a new instance of the <see cref="Investor"/> class.        /// </summary>        /// <param name="name">        /// The name.        /// </param>        public Investor(string name)        {            this.name = name;        }        #endregion        // Gets or sets the stock        #region Public Properties        /// <summary>        /// Gets or sets the stock.        /// </summary>        public Stock Stock { get; set; }        #endregion        #region Public Methods and Operators        /// <summary>        /// The update.        /// </summary>        /// <param name="stock">        /// The stock.        /// </param>        public void Update(Stock stock)        {            Console.WriteLine("Notified {0} of {1}'s " + "change to {2:C}", this.name, stock.Symbol, stock.Price);        }        #endregion    }}// Output:/*Notified Sorros of IBM's change to $120.10Notified Berkshire of IBM's change to $120.10Notified Sorros of IBM's change to $121.00Notified Berkshire of IBM's change to $121.00Notified Sorros of IBM's change to $120.50Notified Berkshire of IBM's change to $120.50Notified Sorros of IBM's change to $120.75Notified Berkshire of IBM's change to $120.75*/

 

           

給我老師的人工智慧教程打call!http://blog.csdn.net/jiangjunshow

這裡寫圖片描述