C # design pattern-simple example of Observer Pattern

Source: Internet
Author: User

During development, a method in one module is often used to call related methods in other modules.

For example, if an error occurs in a system, you can call a method in the module for error handling.

Because there are many error handling operations, these specific operations are encapsulated in other modules.

Call the error operation methods in other modules in the module for special error handling

In this way, you only need to instantiate a module object for error handling in the main system.

And call related methods. The specific methods in other modules will also be executed.

The module for error handling is called the publisher.

Other modules with specific error operations are called subscriber

As long as the publisher publishes information (the method is called)

All subscribers will respond accordingly (the specific method will also be executed)


The most direct method is to reference and instantiate objects in other modules.

Then call its Method

The following is a simple example to use classes to simulate modules.

First, specific error operations

There are three specific error operations in the example.

Email sending, alert, and window Jitter

/// <Summary> /// specific error handling method class (module) 1, this is the subscriber /// </Summary> public class handle1 {// <summary> /// handle the sent email when an error occurs /// </Summary> Public void errorhanding () {console. writeline ("error! An email was sent to the Administrator! ");}}
/// <Summary> /// specific error handling method class (module) 2, this is the subscriber /// </Summary> public class handle2 {// <summary> /// handle the alarm when an error occurs /// </Summary> Public void errorhanding () {console. writeline ("error! Alarm !!!!!!!!!!!!!!!! ");}}

/// <Summary> /// specific error handling method class (module) 3, this is the subscriber // </Summary> public class handle3 {// <summary> // handle window jitter when an error occurs /// </Summary> Public void errorhanding () {console. writeline ("error! I shake !!!!!!!!!!!!!!!!!!!!!!!! ");}}

Dedicated Error Handling Module

/// <Summary> /// class (module) related to system error handling ), this is the information publisher /// </Summary> public class errorabout {// <summary> /// Method for error handling, the main module calls this method to trigger a series of error codes. /// </Summary> Public void errorhanding () {// instantiate each subscriber, call the handle1 handle1 = new handle1 (); handle1.errorhanding (); handle2 handle2 = new handle2 (); handle2.errorhanding (); handle3 handle3 = new handle3 (); handle3.errorhanding ();}}
In the main system:

Class program {static void main (string [] ARGs) {// if an error occurs at this location, you need to handle the error console. writeline ("a serious error occurs in the system and some processing is required ~~~ "); // Instantiate the class related to error handling (publisher) errorabout = new errorabout (); // As long as method 1 of the publisher is executed, all subscriber methods are also executed by errorabout. errorhanding (); console. readkey ();}}
The running result is as follows:


By doing so, you can fully implement the required functions.

But what's wrong?

When an error is found in the main module, a new instance of the Error Module is created, and then the error handling method is called.
In the error module, directly new the instances of each sub-module, and then execute
In this way, the error module and the sub-module are directly coupled together.

This is a process-oriented approach.

When the sub-module method is changed or the error module needs to add a new method to handle the error
Modifying Error modules that have been developed violates the open and closed principle.
Therefore, it is necessary to decouple error modules and submodules (Object-oriented Thinking)


In this case, we use the observer (observer) mode, also known as the publish-subscribe mode.

There are two implementation methods

Method 1: Use delegate
Method 2: Use Interfaces
Both methods isolate error modules and sub-modules.
Operations on both modules are completed in the main module.



Demo1: implement with Delegation

Delegate specific error handling methods

/// <Summary> /// delegate the specific error handling method /// </Summary> Public Delegate void errorhandle ();

/// <Summary> /// class (module) related to system error handling ), this is the publisher of the Information /// </Summary> public class errorabout {// defines the variable private errorhandle entrusted by a specific error handling method; // provide a public void adderrorhanding (errorhandle) method that can be added to internal delegate variables to the outside world. {// Add the passed Method to the delegate variable if (this. errorhandle = NULL) {This. errorhandle = new errorhandle (errorhandle);} else {This. errorhandle + = new errorhandle (errorhandle) ;}}/// <summary> /// error handling method, the main module calls this method to trigger a series of error codes. /// </Summary> Public void errorhanding () {// call the delegate, it is equivalent to calling all methods in the delegate errorhandle ();}}
Pay attention to the use of delegation

External operations cannot be directly delegated.

We must encapsulate a method to provide external users with a safe way to operate internal delegation (why is this a safe way? Because in this method, only the delegate can be added, and no other operations can be performed)

If you directly expose the delegate variable to the outside world

All methods of delegate variables can be called by the outside world.

The original method may be deleted or overwritten.

(This is why the event exists)

This is also an object-oriented idea.


In the main module

Class program {static void main (string [] ARGs) {// if an error occurs at this location, you need to handle the error console. writeline ("a serious error occurs in the system and some processing is required ~~~ "); // Instantiate the class related to error handling (publisher) errorabout = new errorabout (); // Add the subscriber handle1 handle1 = new handle1 () to the publisher; errorabout. adderrorhanding (handle1.errorhanding); handle2 handle2 = new handle2 (); errorabout. adderrorhanding (handle1.errorhanding); handle3 handle3 = new handle3 (); errorabout. adderrorhanding (handle1.errorhanding); // as long as the publisher's method is executed, all subscriber's methods will also be executed by errorabout. errorhanding (); console. readkey ();}}
In this way, the error module and other modules are decoupled.

Any error occurred. The specific operation module has changed.

You only need to modify it in the user-Main module.


Demo2: Implemented Using Interfaces

First, you must provide a unified interface for specific error handling methods (modules)

The publisher can call this interface to implement all subscribers of this interface.


Specific error handling method class (module) interface to be implemented

/// <Summary> /// the interface to be implemented by the specific error handling method class (module, the publisher can use this interface to call the subscriber's method // </Summary> Public interface ihandle {void errorhanding ();}


Specific error handling methods (modules)

/// <Summary> /// specific error handling method class (module) 1, which is subscriber /// </Summary> public class handle1: ihandle {// <summary> // handle the sent email when an error occurs /// </Summary> Public void errorhanding () {console. writeline ("error! An email was sent to the Administrator! ");}}

/// <Summary> /// specific error handling method class (module) 2, which is the subscriber /// </Summary> public class handle2: ihandle {// <summary> // handle the alarm when an error occurs /// </Summary> Public void errorhanding () {console. writeline ("error! Alarm !!!!!!!!!!!!!!!! ");}}

/// <Summary> /// handle window jitter when an error occurs /// </Summary> Public void errorhanding () {console. writeline ("error! I shake !!!!!!!!!!!!!!!!!!!!!!!! ");}


Publisher

/// <Summary> /// class (module) related to system error handling ), this is the information publisher /// </Summary> public class errorabout {// <summary> // a collection of subscriber interfaces /// </Summary> private list <ihandle> handles = new list <ihandle> (); /// <summary> /// you can use this method to add a new subscriber to the set of subscriber interfaces in the main module (specific error handling method) /// </Summary> /// <Param name = "handle"> </param> Public void adderrorhanding (ihandle handle) {handles. add (handle) ;}/// <summary> /// Method for error handling, the main module calls this method to trigger a series of error codes. /// </Summary> Public void errorhanding () {// traverses the foreach (VAR handle in handles) set of subscriber interfaces) {// handle of each error handling method in the execution set. errorhanding ();}}}

Main module

Class program {static void main (string [] ARGs) {// if an error occurs at this location, you need to handle the error console. writeline ("a serious error occurs in the system and some processing is required ~~~ "); // Instantiate the class related to error handling (publisher) errorabout = new errorabout (); // Add the subscriber errorabout to the publisher. adderrorhanding (New handle1 (); errorabout. adderrorhanding (New handle2 (); errorabout. adderrorhanding (New handle3 (); // as long as the publisher's method is executed, all subscriber's methods will also be executed by errorabout. errorhanding (); console. readkey ();}}


Delegate implementation C # simple example of observer mode download:

Click Open Link

Interface implementation C # simple example of observer mode download:

Click Open Link






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.