C # Introduction to observer mode instances

Source: Internet
Author: User

Observer Mode

Observer mode: defines a one-to-many dependency, so that multiple observer objects can listen to a subject object at the same time. When the State of the subject object changes, all observers are notified. When an object needs to change other objects at the same time and does not know how many objects need to be changed, you should consider using the observer mode.

Observer structure:

Use Case: The boss will return to inform the employee of the need to enter the working status.
Define the abstract class of the observer:Copy codeThe Code is as follows: abstract class Observer
{
Protected string name;
Protected ISubject sub;
Public Observer (string name, ISubject sub)
{
This. name = name;
This. sub = sub;
}
Public abstract void Update ();
}

Colleagues watching nbalivestream:Copy codeThe Code is as follows: // use OO
Class NBAObserver: Observer
{
Public NBAObserver (string name, ISubject sub)
: Base (name, sub)
{}
Public override void Update ()
{
// Throw new NotImplementedException ();
Console. WriteLine ("{0} {1} disable nbalivestream and continue working! ", Sub. SubjectState, name );
}
}
// Use events and Delegation
Class NBAObserver2
{
Private string name;
Private ISubject2 sub;
Public NBAObserver2 (string name, ISubject2 sub)
{
This. name = name;
This. sub = sub;
}
Public void CloseStockMarket ()
{
Console. WriteLine ("{0} {1} disable nbalivestream and continue working! ", Sub. SubjectState, name );
}
}

Colleagues who read shares:Copy codeThe Code is as follows: // use OO
Class StockObserver: Observer
{
Public StockObserver (string name, ISubject sub): base (name, sub)
{}
Public override void Update ()
{
// Throw new NotImplementedException ();
Console. WriteLine ("{0} {1} Close the stock market and continue to work! ", Sub. SubjectState, name );
}
}
// Use events and Delegation
Class StockObserver2
{
Private string name;
Private ISubject2 sub;
Public StockObserver2 (string name, ISubject2 sub)
{
This. name = name;
This. sub = sub;
}
Public void CloseNBA ()
{
Console. WriteLine ("{0} {1} Close the stock market and continue to work! ", Sub. SubjectState, name );
}
}

The identity on is the subscriber. The publisher is defined below:Copy codeThe Code is as follows: // use OO
Interface ISubject
{
Void Attach (Observer observer );
Void Detach (Observer observer );
Void y ();
String SubjectState
{
Get;
Set;
}
}
Class Boss: ISubject
{
Private IList <Observer> observers = new List <Observer> ();
Private string action;
Public void Attach (Observer observer)
{
Observers. Add (observer );
}
Public void Detach (Observer observer)
{
Observers. Remove (observer );
}
Public void Policy ()
{
Foreach (Observer o in observers)
{
O. Update ();
}
}
Public string SubjectState
{
Get {return action ;}
Set {action = value ;}
}
}
// Use events and Delegation
Interface ISubject2
{
Void y ();
String SubjectState
{
Get;
Set;
}
}
Delegate void EventHandler ();
Class Boss2: ISubject2
{
Public event EventHandler Update;
Private string action;
Public void Policy ()
{
Update ();
}
Public string SubjectState
{
Get {return action ;}
Set {action = value ;}
}
}

Main function call:Copy codeThe Code is as follows: class Program
{
Static void Main (string [] args)
{
// Observer mode OO implementation
Boss huhansan = new Boss ();
StockObserver tongshi1 = new StockObserver ("name1", huhansan );
NBAObserver tonshi2 = new NBAObserver ("name2", huhansan );
Huhansan. Attach (tongshi1 );
Huhansan. Attach (tonshi2 );
Huhansan. SubjectState = "my 1 is back ";
Huhansan. Policy ();
// Observer Mode c # event implementation
Boss2 huhansan2 = new Boss2 ();
StockObserver2 tongshi3 = new StockObserver2 ("name3", huhansan2 );
NBAObserver2 tonshi4 = new NBAObserver2 ("name4", huhansan2 );
Huhansan2.Update + = new EventHandler (tongshi3.CloseNBA );
Huhansan2.Update + = new EventHandler (tonshi4.CloseStockMarket );
Huhansan2.SubjectState = "I 2 back ";
Huhansan2.Notify ();
Console. ReadKey ();
}
}

A delegate is a type of reference method. Once a delegate is assigned a method, the delegate has the same behavior as the method. The use of delegate methods can have parameters and return values like any other method. A delegate can be seen as an abstraction of a function and a class of a function. A delegate instance represents a specific function. In addition, a delegate can carry multiple methods, and all methods are awakened in turn.

1. Observer Mode
A simple example, such as a modemy, a mouse running, the host is awakened.
Our code may be like this before we know the observer mode.Copy codeThe Code is as follows: // mouse class
Class Mouse
{
Public void Run ()
{
Console. WriteLine ("the mouse is running! ");
}
}
// Primary human
Class Master
{
Public void Wake ()
{
Console. WriteLine ("the master is awake! ");
}
}
// Cat
Class Cat
{
Public void Cry ()
{
Console. WriteLine ("it's called! ");
New Mouse (). Run (); // call the Mouse running method while calling the cat.
New Master (). Wake (); // call the Wake-up method of the Master.
}
}
Class Program
{
Static void Main (string [] args)
{
Cat cat = new Cat ();
Cat. Cry ();
Console. ReadLine ();
}
}

This code can basically implement all functions. However, this method does not take advantage of extensions,
Imagine if, after a cat is called, a dog is also called, is it necessary to re-Add the dog's method to the method?
In other words, after a cat's call, his wife also woke up. Do you want to add his wife's wake-up method to the cat's call method?
Obviously, such code is neither maintenance nor object-oriented code.
The observer mode can effectively solve this problem.
The observer mode defines one-to-many dependencies between objects. When the State of an object changes, all objects dependent on it are notified and automatically updated. In our example, a cat and a mouse, a host, a dog, and a wife are one-to-many dependencies. When a cat is called, all objects dependent on it will automatically perform a certain operation.
The implementation of the observer mode is generally composed of the following four parts.
1. ISubject interface (Abstract target), including the Notify, Register, and UnRegister methods (names can be arbitrarily named by themselves)
2. Subject Class (object target), which implements the ISubject interface. Generally, there is only one
3. IObservable interface (Abstract observer ).
4. The Observer class (entity Observer) implements the IObservable interface. Generally, there are multiple observable interfaces.
The "Register-Notification-logout" icon in observer mode is as follows:
1. The Observer registers himself (Regiester) to the observed object (Subject). The observed object puts the Observer in a Container ). Generally, the Container contains data structures such as Ilist and Arraylist, and stores multiple IObservable interface variables.
2. when the observed object (Subject) changes (AskPriceChanged in), all the Observer (Observer) in the Container (Container) will be notified (using the Notify y method ), in this case, the observer automatically executes some methods.
3. When the observer does not want to continue to observe the observer, the UnRegiester method can be deregistered)
In the above example, after transformation, it becomes:
1. ISubject interface:Copy codeThe Code is as follows: interface ISubject
{
Void y (); // when the topic changes, the notification has the observer
Void Regiester (IObservable o); // observer registration
Void UnRegiester (IObservable o); // The Observer cancels registration. At this time, the observer will not be notified of any changes to the subject.
}

2. Subject Class:Copy codeThe Code is as follows: class Cat: ISubject
{
Private IList <IObservable> observers = new List <IObservable> ();
Public void Policy ()
{
Foreach (IObservable o in observers) // notify the observer one by one
{
O. Action ();
}
}
Public void Regiester (IObservable o)
{
If (o! = Null |! Observers. Contains (o ))
{
Observers. Add (o );
}
}
Public void UnRegiester (IObservable o)
{
If (observers! = Null & observers. Contains (o ))
{
Observers. Remove (o );
}
}
Public void Cry ()
{
Console. WriteLine ("it's called! ");
Notify ();
}
}

3. IObservable interface:Copy codeThe Code is as follows: interface IObservable
{
Void Action (); // the Action that the observer performs on Theme Changes
}

4. Observer class (2, Mouse and Master)Copy codeThe Code is as follows: class Mouse: IObservable
{
Public void Action ()
{
Console. WriteLine ("rat is running! ");
}
}
Class Master: IObservable
{
Public void Action ()
{
Console. WriteLine ("the master is awake! ");
}
}

5. Main ProgramCopy codeThe Code is as follows: Mouse mouse = new Mouse ();
Master master = new Master ();
Cat cat = new Cat ();
Cat. Regiester (mouse );
Cat. Regiester (master );
Cat. Cry ();
Console. ReadLine ();

In this way, the observer mode is implemented. By registering the dependency class to the subject class, all the dependent classes are notified when the subject class changes. If you need extension, for example, the dog in the above example is also called, we can define a dog class, and then register the dog object to the cat class in the main program. If you do not want to depend on the cat class, you can use the UnRegiester method to unbind it.
At the same time, this is also in line with the design of high cohesion, low coupling principles.
.Copy codeThe Code is as follows: using System;
Using System. Collections. Generic;
Using System. Text;
Namespace Sample
{
Public delegate void CatCallEventHandler ();
Class Program
{
Static void Main (string [] args)
{
Cat cat = new Cat ();
Mouse mouse = new Mouse (cat );
Master master = new Master (mouse );
Cat. Call ();
}
}
Class Cat
{
Public event CatCallEventHandler catevent;
Public void Call ()
{
Console. WriteLine ("meow .....");
Catevent ();
}
}
Class Mouse
{
Public event CatCallEventHandler mouseevent;
Public Mouse (Cat cat)
{
Cat. catevent + = new CatCallEventHandler (this. MouseRun );
}
Public void MouseRun ()
{
Console. WriteLine ("mouse run ");
Mouseevent ();
}
}
Class Master
{
Public Master (Mouse mouse)
{
Mouse. mouseevent + = new CatCallEventHandler (this. JingXing );
}
Public void JingXing ()
{
Console. WriteLine ("the master is awakened ");
}
}
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.