This note is excerpted from: https://www.cnblogs.com/PatrickLiu/p/7928521.html Record the learning process for future reference.
I. Introduction
Today we're going to talk about the fourth pattern of behavioral design pattern -- the observer pattern, first from the name. The observer model can be understood as that since there is "Observer", there must be "observed". "Observer"
Monitor the "observed". If the "observed" acts, the "Observer" will make corresponding actions to respond. Does it sound like "spy war"? Such as "spy film heavy" and other excellent films.
In real life, there are many examples of the observer model. For example, when we subscribed to newspapers in the 1980s and 1990s, we would receive newspapers regularly because we subscribed to them. Banks can send SMS messages to depositors,
It's also an example of a good use of the observer model, because we subscribe to the bank's SMS business, and will be notified when our account balance changes. There are many more, I will not list them one by one, and give full play to everyone's
Imagine. Now, let's see how the pattern is implemented.
II. Introduction to the observer model
Observer Pattern: English name -- Observer Pattern; classification -- behavior type.
2.1. Motivation
In the process of software construction, we need to establish a "Notification dependency" for some objects. When the state of an object (target object) changes, all dependent objects (observer object) will be notified.
If the dependency is too close, the software will not be able to resist the change. Using object-oriented technology, this kind of dependency can be weakened, and a stable dependency can be formed, so as to realize the software body
Loose coupling of the system structure.
2.2 intention
Defines a one to many dependency between objects so that when an object's state changes, all objects that depend on it are notified and automatically updated. ——Design mode GoF
2.3 structure diagram
2.4 composition of mode
It can be seen that in the structure chart of observer mode, there are the following roles:
1) abstract Subject: abstract Subject saves references of all observer objects in a list, and provides operations for adding and deleting observer objects. Abstract Subject role is also called abstract observed role
Observer role, usually implemented by abstract class or interface.
2) Abstract Observer role: defines an interface for all specific observers, and updates itself when notified of the subject, which is generally implemented by an abstract class or interface.
3) concrete subject: implements abstract subject interface, which is also called concrete observed role.
4) concrete Observer: implements the interface required by the abstract observer role, so as to coordinate its own state with the state of the subject.
2.5 implementation of observer mode
For example, when we subscribe to the bank SMS service, when our account changes, we will receive the corresponding SMS. Similar to the wechat subscription number, today
We take the SMS service of subscription bank as an example to talk about the implementation of observer mode. The implementation code is as follows:
class Program { /// <summary> /// Abstract interface of bank SMS system is the observed--This type is equivalent to the abstract theme role Subject. /// </summary> public abstract class BankMessageSystem { protected IList<Depositor> observers; //Constructor initializes the observer list instance protected BankMessageSystem() { observers = new List<Depositor>(); } //Increase reserved account public abstract void Add(Depositor depositor); //Delete reservation account public abstract void Delete(Depositor depositor); //Notify depositors public void Notify() { foreach (Depositor depositor in observers) { if (depositor.AccountIsChanged) { depositor.Update(depositor.Balance, depositor.OperationDateTime); //After the account changes and notification, it can be considered that the account has not changed. depositor.AccountIsChanged = false; } } } } /// <summary> /// The SMS system of Guangdong bank is the observed--This type is equivalent to a specific topic role ConcreteSubject. /// </summary> public sealed class GuangDongBankMessageSystem : BankMessageSystem { //Increase reserved account public override void Add(Depositor depositor) { //Should you first determine whether the user has made an appointment? If there is no appointment, it will be added to the list, which is simplified here. observers.Add(depositor); } //Delete reservation account public override void Delete(Depositor depositor) { //Should we first judge whether the user has an appointment? If yes, delete it. Otherwise, do not operate. It is simplified here. observers.Remove(depositor); } } /// <summary> /// Abstract interface of depositor--Equivalent to the role of abstract observer( Observer) /// </summary> public abstract class Depositor { //The name of the depositor, assuming it is unique. public string Name { get; private set; } //Balance of depositor public int Balance { get; private set; } //Account operation time public DateTime OperationDateTime { get; set; } //Whether the account has changed public bool AccountIsChanged { get; set; } //Initialization status data protected Depositor(string name, int total) { Name = name; Balance = total; //Total deposit equals balance AccountIsChanged = false; //No change in account } //Withdraw money public void GetMoney(int num) { if (num <= Balance && num > 0) { Balance -= num; AccountIsChanged = true; OperationDateTime = DateTime.Now; } } //Update depositor status public abstract void Update(int currentBalance, DateTime dateTime); } /// <summary> /// Specific depositors in Guangdong--Equivalent to a specific observer role ConcreteObserver /// </summary> public sealed class GuangDongDepositor : Depositor { public GuangDongDepositor(string name, int total) : base(name, total) { } public override void Update(int currentBalance, DateTime dateTime) { Console.WriteLine(string.Format(Name + ",Your account balance has changed. Time:{0},Current balance:{1}Yuan.", dateTime.ToString(), currentBalance.ToString())); } } static void Main(string[] args) { #region Observer mode //Suppose there are three savers, all of them are martial arts experts, and they are also rich. Depositor huangFeiHong = new GuangDongDepositor("Huang Feihong", 3000); Depositor fangShiYu = new GuangDongDepositor("Fang Shi Yu", 1300); Depositor hongXiGuan = new GuangDongDepositor("Hong Xi Guan", 2500); BankMessageSystem guangDongBank = new GuangDongBankMessageSystem(); //The three began to subscribe to the bank's SMS service guangDongBank.Add(huangFeiHong); guangDongBank.Add(fangShiYu); guangDongBank.Add(hongXiGuan); //In the morning, Huang Feihong took 100 yuan huangFeiHong.GetMoney(100); guangDongBank.Notify(); //At noon, Huang Feihong and Fang Shiyu took 200 yuan each huangFeiHong.GetMoney(200); fangShiYu.GetMoney(200); guangDongBank.Notify(); //In the evening, all three of them took money huangFeiHong.GetMoney(300); fangShiYu.GetMoney(300); hongXiGuan.GetMoney(300); guangDongBank.Notify(); Console.Read(); #endregion } }
The operation results are as follows:
Some of the trouble with the observer model is the handling of the state. You can have a detailed experience. The model still needs to be written and practiced more, so it's not hard to understand the truth.
III. key points of the realization of the observer model
Using object-oriented abstraction, Observer mode enables us to independently change the target and Observer (the change in object-oriented means not changing the code, but extending, subclassing and implementing the interface), so as to
The dependence between them is loose coupling. When a target sends a notification, it does not need to specify an observer, and the notification (which can carry the notification information as a parameter) will be propagated automatically. The observer decides whether to subscribe to the notification,
The target object knows nothing about it.
In the event of C ා, the delegate acts as the abstract Observer interface, while the object providing the event acts as the target object. Delegation is a more loosely coupled design than the abstract Observer interface.
3.1 advantages of observer mode
1) observer pattern realizes the separation of presentation layer and data logic layer, defines a stable update message delivery mechanism, and abstracts the update interface, so that there can be a variety of different presentation layers, namely observers.
2) the observer model establishes an abstract coupling between the observed and the observer. The observed does not know any specific observer, but only keeps the list of abstract observers, each specific observer
All conform to the interface of an abstract observer.
3) observer mode supports broadcast communication. All registered observers will be notified by the observed.
3.2 disadvantages of observer mode
1) if an observed person has many direct and indirect observers, it will take a lot of time to notify all the observers.
2) although the observer mode can make the observer know that the observed object has sent changes at any time, the observer mode has no corresponding mechanism to make the observer know how the observed object changes.
3) if there is a circular dependency between the observed, the observed will trigger a circular call between them, resulting in system crash, which should be paid special attention to when using the observer mode.
IV. implementation of observer pattern in. NET
In fact, the observer pattern implemented in Net has made some changes. Delegate or event is used to implement the observer pattern. Events we all know that you can register the events of a control. When the action of a control is triggered,
The corresponding event will be executed. During the execution of the event, we can do the relevant reminder business. Let's not talk about the implementation of observer mode in Net. If you don't understand, you can have a look at the relevant committees
Relevant information of entrusted or incident.
V. summary
It's easy to understand this pattern with examples. We can't copy the use of the pattern. To understand it, of course, it's necessary to connect and write more code. Our consistent purpose of using the pattern is through refactoring and iteration,
Implement the corresponding pattern in our code.