. Net Design Pattern (Observer Pattern) and observerpattern
1. Introduction to observer mode (Brief Introduction)
The observer mode defines a one-to-many dependency, allowing multiple observer objects to listen to a topic object at the same time. When the status of the topic object changes, all observer objects are notified, enable them to automatically update themselves.
2. What To Solve)
When an object needs to change other objects at the same time, and you do not know how many objects need to be changed, you should consider using the observer mode.
The work done by the observer mode is actually to remove coupling, so that both sides of the coupling depend on abstraction, rather than on specifics, so that their changes will not affect the changes on the other side.
Iii. Observer mode Analysis (Analysis) 1. Observer mode structure
Subject Class: It stores all references to the observer object in one aggregation. Each topic can have any number of observers. Abstract topics provide an interface to add and delete observer objects.
public void Notify(){ foreach(Observer o in observers) { o.Update(); }
ConcreteSubject class: stores the status of a subject in a specific observer object, and sends a notification to the observer of all registrants when the internal status of the subject changes.
Observer class: Abstract Observer, which defines an interface for all specific observers and updates itself when receiving notification from the topic.
ConcreteObserver: a specific observer that implements the update interface required by the abstract observer role, so that the state of the observer can be consistent with the state of the topic.
2. Source Code
1. Subject Class, Subject or abstract notification
Public abstract class Subject {private IList <Observer> observers = new List <Observer> (); /**/<summary> */Add observer */</summary> */<param name = "Observer"> observer </param> */public void Attach (observer Observer) {observers. add (observer );} /**/<summary> */remove the observer */</summary> */<param name = "Observer"> observer </param> */public void Detach (observer Observer) {observers. remove (observer);}/**/<summary> */notification Observer */</summary> */public void handle Y () {foreach (observer o in observers) {o. update ();}}}
2. ConcreteSubject class, subject or notification recipient
Public class ConcreteSubject: Subject {private string _ subjectState; /*/<summary> * // */specific observed status * // */</summary> */public string SubjectState {get {return (_ subjectState );} set {_ subjectState = value ;}}}
3. The Observer abstracts the Observer and defines an interface for all the specific observers.
public abstract class Observer{ public abstract void Update();}
4. Specific observer of ConcreteObserver
/// <Summary> /// specific observer, implement the update interface required by the abstract Observer role // to coordinate its status with the topic status /// </summary> public class ConcreteObserver: Observer {private string name; private string observerState; private ConcreteSubject subject; public ConcreteSubject Subject {get {return subject;} set {subject = value ;}} public ConcreteObserver (ConcreteSubject subject, string name) {this. subject = subject; this. name = name;} public override void Update () {observerState = subject. subjectState; Console. writeLine ("the new status of the observer {0} is {1}", name, observerState );}}
5. client code
static void Main(string[] args){ ConcreteSubject cs = new ConcreteSubject(); cs.Attach(new ConcreteObserver(cs, "James")); cs.Attach(new ConcreteObserver(cs, "Jane")); cs.SubjectState = "OK"; cs.Notify(); Console.Read();}
3. program running result
4. Observer instance analysis (Example)
1. Scenario
Assume that the opening price of a stock is RMB 16.50, and the price has been declining since the stock was listed, and the price has declined at a rate of RMB 1.00.
When the stock falls to 12.00 yuan, the stockholders live to buy the stock.
When the stock dropped to 8.05 yuan, the shareholder Jane bought the stock.
2. Observer instance Structure
Stock class, abstract notifier
Defines the delegate PriceChangedHandler and calls the event parameter StockDetailsArgs.
Declared the event PriceChanged.
The method OnPriceChanged is called when the stock falls. This method triggers the event PriceChanged.
The AttachEvent method is used to add an observer to an object.
StockDetailArgs class, the event parameter inherits from the EventArgs class, and the tree-like CurrentPrice is used to deliver price data
The IObserver interface and the Observer class are as follows:
Stoc_PriceChanged method: This method is called when the stock is at a price reduction of 1.00 yuan. When the price falls to the buyer's price, and the stock is not purchased by others, the purchase is performed.
Opening Price: 16.50
Closing Price: 5.50
When the price drops to 12.00, the observer lives to buy this stock
When the price drops to 8.05, the observer Jane buys the stock.
3. Code
1. Stock
Public class Stock {private double _ openPrice; private double _ closePrice; public delegate void PriceChangedHandler (object sender, StockDetailArgse); public event PriceChangedHandler PriceChanged; public double OpenPrice {get {return _ openPrice;} set {_ openPrice = value ;}} public double ClosePrice {get {return _ closePrice ;}set {_ closePrice = value ;}} public void StartTrading () {double Current; // Current price decrements by $1.00 as the stock is traded current = OpenPrice; while (current> ClosePrice) {// Stock is falling in increments of $1.00 current = current-1.00; // Call the method to raise the event OnPriceChanged (current ); // Simulate a delayof 2000 ms between market price updates System. threading. thread. sleep (2000) ;}} protected void OnPriceChanged (double currentMarket Price) {// Any handlers attached to this event? If (PriceChanged! = Null) {StockDetailArgs args = new StockDetailArgs (); args. currentPrice = currentMarketPrice; Console. writeLine ("current stock price:" + args. currentPrice. toString (); // Raise the event PriceChanged (this, args );}} /// <summary> /// add an observer /// </summary> /// <param name = "observer"> observer </param> public void AttachEvent (IObserver observer) {PriceChanged + = newPriceChangedHandler (observer. stoc_PriceChanged );}}
2. Event parameter StockDetailArgs
public class StockDetailArgs: EventArgs{ private double _currentPrice; public double CurrentPrice { get { return _currentPrice; } set { _currentPrice = value; } }}
3. Observer interface IObserver
public interface IObserver{ void Stoc_PriceChanged(object sender, StockDetailArgs e);}
4. Specific Observer
Public class Observer: IObserver {private string _ investorName; private double _ buyPrice; private Stock _ stoc; private bool _ hasBoughtStock = false; public string InvestorName {get {return _ investorName ;} set {_ investorName = value ;}} public double BuyPrice {get {return _ buyPrice ;}set {_ buyPrice = value ;}} public Stock Stoc {get {return _ stoc ;} set {_ stoc = value ;}} public Obser Ver (string investorName, double buyPrice) {this. investorName = investorName; this. buyPrice = buyPrice;} public void Stoc_PriceChanged (object sender, StockDetailArgs e) {if (e. currentPrice <= BuyPrice & _ hasBoughtStock = false) {Console. writeLine (string. format ("{0} bought the stock at Price = {1. ", InvestorName, e. CurrentPrice); _ hasBoughtStock = true ;}}}
5. client code
Static void Main (string [] args) {Stock stock = new Stock (); stock. openPrice = 16.50; stock. closePrice = 5.50; Observer james = new Observer ("Smart Life", 12.00); Observer jane = new Observer ("jane", 8.05); stock. attachEvent (james); stock. attachEvent (jane); stock. startTrading (); Console. read ();}
4. program running result