Design Pattern note (19)-Observer pattern (behavior pattern)

Source: Internet
Author: User
Tags sendmsg
Document directory
  • Gof Definition
  • Motivation
  • Key points of the observer Mode
Gof Definition

Defines a one-to-many dependency between objects so that when the state of an object changes, all objects dependent on it are notified and automatically updated.

Motivation

In the process of building software, we need to establish a "Notification dependency" for some objects-the state of an object (target object) changes, and all dependent objects (Observer objects) will be notified. If such dependency is too tight, the software cannot well resist changes. Using object-oriented technology, you can weaken this dependency and form a stable dependency. To achieve loose coupling of the software architecture.

In this scenario, the bank's ATM will send text messages and e-mails to the user after the bank account is saved or removed, so there will be three objects: bankaccount emailer mobile, the Code is as follows:

Public class bankaccount {emailer; mobile; Public void withdraw (INT data) {// process the stored or retrieved emailer. sendemail (""); mobile. sendmsg ("") ;}} public class emailer {public void sendemail (string to) {// send email }} public class mobile {public void sendmsg (string phonenumber) {// send SMS }}

In the code above, there is a strong dependency between bankaccount and emailer mobile. Changes in emailer and mobile will have a great impact on bankaccount, the next step is to make bankaccount not dependent on specific classes such as emailer and mobile, but on their abstraction. The abstract is usually stable, in this way, the dependency between the bankaccount and the abstraction is relatively weak. The Code is as follows:

Public class useraccountargs {Public String email {Get; set;} Public String phonenumber {Get; set;} public useraccountargs (string email, string phonenumer) {email = Email; phonenumber = phonenumer;} public interface iaccountobserver {void Update (useraccountargs ARGs);} public class emailer: iaccountobserver {public void Update (useraccountargs ARGs) {console. writeline ("the message has been sent to the mailbox:" + args. email) ;}} public class Mobile: iaccountobserver {public void Update (useraccountargs ARGs) {console. writeline ("the message has been sent to the mobile phone:" + args. phonenumber) ;}} public class bankaccount {list <iaccountobserver> List = new list <iaccountobserver> (); Public void withdraw (INT data) {// process the stored or retrieved if (data> 0) {console. writeline ("your account has been saved to" + Data + "");} else {console. writeline ("your account has been taken out" + math. ABS (data) + "RMB");} useraccountargs ARGs =
New useraccountargs ("oec2003@gmail.com", "1388888 ***"); foreach (iaccountobserver observer in list) {observer. update (ARGs) ;}} public void addobserver (iaccountobserver observer) {list. add (observer);} public void removeobserver (iaccountobserver observer) {list. remove (observer) ;}//< summary> /// client call //</Summary> class program {static void main (string [] ARGs) {bankaccount = new bankaccount (); bankaccount. addobserver (New emailer (); bankaccount. addobserver (new mobile (); bankaccount. withdraw (-500 );}}

The running result is as follows:

The above improved code only abstracts emailer and mobile. In fact, bankaccount may be unstable, so you also need to abstract bankaccount. The improved code is as follows:

Public class useraccountargs {Public String email {Get; set;} Public String phonenumber {Get; set;} public useraccountargs (string email, string phonenumer) {email = Email; phonenumber = phonenumer;} public interface iaccountobserver {void Update (useraccountargs ARGs);} public class emailer: iaccountobserver {public void Update (useraccountargs ARGs) {console. writeline ("the message has been sent to the mailbox:" + args. email) ;}} public class Mobile: iaccountobserver {public void Update (useraccountargs ARGs) {console. writeline ("the message has been sent to the mobile phone:" + args. phonenumber) ;}} public abstract class subject {list <iaccountobserver> List = new list <iaccountobserver> (); protected virtual void Policy (useraccountargs ARGs) {foreach (iaccountobserver observer in List) {observer. update (ARGs) ;}} public void addobserver (iaccountobserver observer) {list. add (observer);} public void removeobserver (iaccountobserver observer) {list. remove (observer) ;}} public class bankaccount: Subject {public void withdraw (INT data) {// process the stored or retrieved if (data> 0) {console. writeline ("your account has been saved to" + Data + "");} else {console. writeline ("your account has been taken out" + math. ABS (data) + "RMB");} useraccountargs ARGs =
New useraccountargs ("oec2003@gmail.com", "1388888 ***"); y (ARGs );}} /// <summary> // client call // </Summary> class program {static void main (string [] ARGs) {bankaccount = new bankaccount (); bankaccount. addobserver (New emailer (); bankaccount. addobserver (new mobile (); bankaccount. withdraw (-500 );}}

In this way, the unstable objects are abstracted, and the dependency between the abstract and the abstract is dependent on each other to facilitate expansion.

Structure of the observer mode:

The comparison has the following relationships with the above Code:

  • Subject: Subject
  • Observer: iobserver
  • Concretesubject: bankaccount
  • Concreteobserver: emailer mobile

Implementation of basic code:

Public abstract class subject {private list <observer> List = new list <observer> (); /// <summary> /// add an observer /// </Summary> /// <Param name = "Observer"> </param> Public void attach (Observer observer) {list. add (observer );} /// <summary> /// remove the observer /// </Summary> /// <Param name = "Observer"> </param> Public void detach (Observer observer) {list. remove (observer);} public void Policy () {foreach (Observer observer in list) {observer. update () ;}}/// <summary> // abstract observer class /// </Summary> public abstract class observer {public abstract void Update ();} /// <summary> /// specific notifier /// </Summary> public class concretesuject: Subject {Public String subjectstate {Get; set;} public concretesuject (string subjectstate) {This. subjectstate = subjectstate; }}/// <summary> // specific observer // </Summary> public class concreteobserver: Observer {private concretesuject _ subject; private string _ name; public concreteobserver (concretesuject subject, string name) {This. _ subject = subject; this. _ name = Name;} public override void Update () {console. writeline ("Observer:" + _ name + "status:" +
_ Subject. subjectstate) ;}//< summary> /// client call //</Summary> class program {static void main (string [] ARGs) {concretesuject CS1 = new concretesuject (""); concretesuject CS2 = new concretesuject (""); cs1.attach (New concreteobserver (CS1, "oec2003 ")); cs1.attach (New concreteobserver (CS2, "oec2004"); cs1.y y ();}}
Key points of the observer Mode
  • With object-oriented abstraction, the observer mode allows us to independently change the object and the observer, so that the dependency between the two can be loosely coupled.
  • When the target sends a notification, no observer is required. The notification (which can carry the notification information as a parameter) will be automatically transmitted. The observer decides whether to subscribe to notifications by himself, and the target object knows nothing about this.
  • In the C # event, the delegate acts as an abstract observer interface, and the object that provides the event acts as the target object. Delegation is a more loosely coupled design than the abstract observer interface.

Return to the beginning (INDEX)

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.