Design mode: Use C # delegate to improve OBServer mode
Summary
Observer mode is a model we have applied because it defines the message delivery of a single data source multi-view structure and object design, so almost all of the multi-layer applications that will represent layers and data logic layers. It can use the OBServer mode. This article will analyze the C # language to implement the code of this mode, and some shortcomings exist for this mode, using C #'s new feature delegate to try some improvements to this mode.
table of Contents
Observer mode Introduction Application instance mode Implementation mode analysis Improved OBServer mode to implement complete source code
Observer mode introduction
In order to let more people can understand this article, before this, let's first understand the basic concept of the OBServer mode.
Mode Name: OBServer
Structural map:
intention:
Define a pair of dependencies between objects, when the status of an object changes, all objects that depend on its object are notified and automatically updated.
applicability:
One aspects are dependent on the other aspect. The two are encapsulated in separate objects to make them independently change and reuse.
When changes to an object requires simultaneous changes, don't know how many objects have to be changed.
When an object must notify other objects, it can't assume who other objects are. In other words, you don't want these objects to be closely coupled.
Applications
When writing multi-storey applications, we usually separate the representation layer and data logic layers, such as a very common view / document structure, the result of this design method is usually used to use multi-view simultaneously represent a single data source. For example, a web site can easily have an HTML page for your computer and a WAP page for your phone. When using this structure, in order to maintain the consistency of the data display, the data source must be required to inform each of the representations of each one and its binding representation when data changes. But the problem is that the data layer itself does not know how many different representations in the end reflect its data content. Therefore, it is necessary to design a set of effective mechanisms to complete this goal.
Mode implementation
We first see the conventional C # implementation code from the "Design Mode Mini Manual".
Subject (abstract target):
The target knows its observer. There can be any other observer to observe the same goal.
// class Subject {// implementation code because they do not know how many viewers, so the establishment of an observer list private ArrayList list = new ArrayList (); private string strImportantSubjectData = "Initial"; public string ImportantSubjectData {get {return strImportantSubjectData } set {strimportantsubjectdata = value;}} public void attach (observer o) {list.add (o); o.observedsubject = this;} public void detach (o) {} public void notify () {// After the data changes, the traversal list notifies the observer Foreach (Observer O IN List) {o.Update ();}}
Observer (abstract observer):
A update interface is defined for objects that need to be notified when the target changes.
abstract class Observer {// the object contains a protected Subject s need to observe; public Subject ObservedSubject {get {return s;} set {s = value;}} abstract public void Update ();} ConcreteSubject (target entities, where considerable Data logic layer):
Deposit the relevant state into each ConcRelleSubject object.
When it changes, it is a notification to each of its observes.
// There is basically nothing here, and the data can be placed in getState () Class ConcreteSubject: Subject {public void getState ()} public void setState ()}}
ConcreteObserver (entity observer, it is equivalent to the representation layer):
Maintain a reference to ConcreteSubject.
Save the status, these states should be consistent with the status of the target.
Implement the OBServer update interface to keep your own state with the target status.
class ConcreteObserver: Observer {private string observerName; public ConcreteObserver (string name) {observerName = name;} override public void Update () {// out of the display data Console.WriteLine ( "In Observer {0}: data from subject = { 1} ", observername, simportantsubjectdata;}}
Main function:
public class Client {public static int Main (string [] args) {ConcreteSubject s = new ConcreteSubject (); ConcreteObserver o1 = new ConcreteObserver ( "first observer"); ConcreteObserver o2 = new ConcreteObserver ( "second observer"); // Register Observer s.attach (O1); S.Attach (O2); s. ImportantsubjectData = "this is important subject data"; sNotify (); return 0;}}}
Mode analysis
The advantage of the OBServer mode is to achieve separation of the layer and the data logic layer, and define a stable update message transfer mechanism, the category is clear, and the update interface is abstracted, so that there are various different representations (observer) . However, its disadvantage is that each appearance object must inherit this abstraction interface class, which has caused some inconvenience, such as an exterior object written by others, does not inherit the abstract class, or the interface is wrong, we hope not Modify this class directly using it. Although Adapter mode can be applied to some extent, this problem is solved, but it will cause more complex and artistic design to increase the error rate.
C # As an advanced modern object-oriented language, not only the essence of many languages, but also creates some very useful new features. After learning the C # language, I found that using C # unique delegate can come to better solve this problem.
Improved OBServer mode implementation
First define a delegate:
Delegate Void UpdatedLate (SUBJECT): Subject:
class Subject {private string strImportantSubjectData = "Initial"; // define an event container, instead of the list of objects in front of the observer public event UpdateDelegate UpdateHandle; public string ImportantSubjectData {get {return strImportantSubjectData;} set {strImportantSubjectData = value;}} public void NOTIFY () {// Send event if (updateHandle! = Null) UpdateHandle (StrimportantsUbjectData);}}
Observer (abstract observer):
No, because there is no need to abstract interface classes, you can save the abstract observer class.
ConcreteSubject:
// No change Class ConcreteSubject: Subject {public void getState ()} public void setState ()}}}
ConcreteobServer (entity observer):
// In order to clearly explain the problem, two entity observer is defined here. Note that there is no relationship between them Class Observer1 {Private String ObserverName; public observer1 (String name) {ObserverName = Name;} public void update1 (string ImportantSubjectData) {Console.WriteLine ( "In Observer {0}: data from subject = {1}", observerName, ImportantSubjectData);}} class observer2 {private string observerName; public observer2 (string name) {= name observerName; } public void update2 (String ImportantSubjectData) {Console.WriteLine ("IN Observer {0}: Data from Subject = {1}", ObserverName, ImportantsUbjectData;}}
Main function:
public class Client {public static int Main (string [] args) {ConcreteSubject s = new ConcreteSubject (); Observer1 o1 = new Observer1 ( "first observer"); Observer2 o2 = new Observer2 ( "second observer"); // to Target registration objects two observers, please note that just add two methods, // does not need to care about how to come, and do not need to care about how to call them. s.UpdateHandle = new UpdateDelegate (o1.Update1); s.UpdateHandle = new UpdateDelegate (o2.Update2); s.ImportantSubjectData = "This is important subject data"; s.Notify (); return 0;}} In In this code, did not see the list, did not see the traversal operation, did not see how the update is called, and even the abstraction and abstract interfaces of the classes that are connected together, but the target object can Send data update information one by one to each observer object, and more easily add new different observer objects, do not need to know where it is inherited, and does not need to unify their interface calling methods. All this is attributed to the flexible powerful C #.
Complete source code
The following is a complete source code:
namespace Observer_DesignPattern {using System; delegate void UpdateDelegate (string SubjectData); class Subject {private string strImportantSubjectData = "Initial"; public event UpdateDelegate UpdateHandle; public string ImportantSubjectData {get {return strImportantSubjectData;} set {strImportantSubjectData = value;}} public void Notify () {if (UpdateHandle = null!) UpdateHandle (strImportantSubjectData);}} class ConcreteSubject: Subject {public void GetState () {} public void SetState () {}} class observer1 {private string observerName; public observer1 (string name ) {observerName = name;} public void Update1 (string ImportantSubjectData) {Console.WriteLine ( "In Observer {0}: data from subject = {1}", observerName, ImportantSubjectData);}} class observer2 {private string observerName; public Observer2 {ObserverName = name;} public void update2 (String Impo) {Console.Writeline ("in Observer {0}: data from subs subject = {1}", ObserverName, IMPOR tantSubjectData);}} public class Client {public static int Main (string [] args) {ConcreteSubject s = new ConcreteSubject (); Observer1 o1 = new Observer1 ( "first observer"); Observer2 o2 = new Observer2 ( "second observer" ); s.UPDATEHANDLE = new updatedelegate (o1.Update1); s.UpdateHandle = new updatedlegate (o2.Update2); s.importantsubjectData = "this is important subject data"; s.Notify (); return 0;} }} author: Lu Yan
Related resources: with sound access new year fireworks animation effects - html-code