C # Delegate implementation simple design pattern tutorial

Source: Internet
Author: User
Tags abstract foreach anonymous bool inheritance

This brief introduction of the use of the delegate. Many of the articles commissioned will say: The concept of the Commission and the event is like a hurdle, passed the threshold of the people, think it is too easy, and no past people every time to see the delegates and events feel panic. It is true that this thing, like the first pointer to the C language, is a very tangled sensation, and it is always felt to call a method directly, and why not to define a delegate. In fact, in C # Many of the technology is to reuse and simplify the code, the delegate is no exception, many use C # polymorphism to achieve the design pattern can be used to rewrite the way, can be understood as a lightweight design model bar. The blogger intends to draw a special share of the following polymorphism and delegate implementation of design patterns and similarities and differences. This article first introduces the use of simple delegates.





What is a delegate: a Delegate in C # (Delegate) is similar to a pointer to a function in C or C + +. In the words of bloggers, a delegate is a reference type that allows the method name to be passed as a parameter. It defines the type of the method, which is the abstraction of the method, and conversely, the method can be interpreted as an instance of the delegate, such as public delegate void Testdelegate (String str), which defines all parameter types as String, An abstraction of a method that does not return a value.





Second, what to use the delegate: Remember the blogger just started to do the project when he saw commissioned the writing on the head big, always feel that there is nothing to look for, the only advantage seems to be that the code looks cool ~ ~ With the accumulation of work, it is found that some small requirements of the project to use this lightweight delegate to achieve when it can really reduce the amount of code.





third, the use of the Commission:





1. The delegate type within the. Net Framework: A friend who has used a delegate may have noticed that there are two types of delegate variables defined in C # that basically meet our general needs.





(1) Delegate of action type: C # defines the action delegate for abstracting a method that has no return value. To go to the definition of the action variable is the simplest form of it:





Summary:


Encapsulates a method that does not have parameters and does not return a value.


[Typeforwardedfrom ("System.core, version=3.5.0.0, Culture=neutral, publickeytoken=b77a5c561934e089")]


public delegate void Action ();





It is defined as a delegate that has no parameters to return a value. The action also provides 16 generic delegates that define incoming parameters for the method:


Let's look at how they use it, we first define the test methods:

private static void Test5 (int a, int b, int c)
{
//...
}
No parameter no return value
private static void Test1 ()
{
Console.WriteLine ("Func Test1, no Parameter");
}
There are parameters without return value
private static void Test2 (String str)
{
Console.WriteLine ("Func Test2, Parameter is" + str); 
  }
//No parameters have return value
private static Object Test3 ()
{
Console.WriteLine ("Func Test3, Parameter");
Return Guid.NewGuid (). ToString ();
}
Parameter has return value
private static Object Test4 (String strres)
{
Console.WriteLine ("Func Test4, Parameter and Re    Turn Value ");
return strres;
}


Call:

static void Main (string[] args)
{
//1. No parameter no return value method
var oAction1 = new Action (Test1);
Oaction1.invoke ();//Call Way one
oAction1 ();//Call Mode two
//2. There is no return value
var oAction2 = new Action<int, int, int    > (TEST5);
Oaction2.invoke (1, 2, 3);
OAction2 (1, 2, 3);
anonymous method invocation
var oAction3 = new Action<int, int, int> ((a,b,c) => {
//...
});
Oaction3.invoke (1, 2, 3);
}







(2) Func type of delegate: Remember the parameters of methods such as the extension method where (), Select () in LINQ. public static ienumerable&lt;tsource&gt; where&lt;tsource&gt; (this ienumerable&lt;tsource&gt; source, func&lt; TSource, bool&gt; predicate). The argument here is a Func type of delegate. C # inside Func type delegates are used to handle methods with parameters that have return values. Not much to say, on the code:





static void Main (string[] args)


{


var oFunc1 = new func&lt;object&gt; (TEST3);


var ofuncRes1 = Ofunc1.invoke ();


var oFunc2 = new func&lt;string, object&gt; (TEST4);


OFUNC2 ("a");


}








Know the Func method can be pushed to think of our magic Lamada expression, in fact, Lamada expression is an anonymous delegate.





var lsttest = new list&lt;string&gt; ();


var lstres = lsttest.where (x =&gt; x.contains ("_"));





The Lamada expression in this where we disassemble him:





private static bool Testwhere (string x)


{


Return X.contains ("_");


}





var ofunc = new func&lt;string, bool&gt; (Testwhere);


Lstres = Lsttest.where (Ofunc);





is not the same as ~ ~





2, Custom delegate:





public delegate void Testdelegate (String str);





In fact, many people should have written their own action, Func type of delegate. It is also simple to define a generic delegate yourself:





public delegate void Myaction&lt;in t&gt; ();


Public delegate TResult Myfunc&lt;in T, out tresult&gt; (t arg);





In fact, the use of the system and the action and Func basically no difference.





3. The merger and dismantling of the delegates are shared in the event. This article and the ...





4, if according to the above method to use the delegate, it really is to be awkward dead, because the call method directly with the method name call is good, why also want to define a delegate variable to call, this is not to complicate the simple problem. Indeed, the above is just for the purpose of introducing the code written by the delegate, the actual project will not be so used. In fact, a delegate is typically used in a project to pass a delegate variable as a parameter or a function callback. Look at the following code:





Class&nbsp;program {&nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;void&nbsp;main (String[]&nbsp;args) &nbsp;&nbsp;&nbsp; &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;person
&nbsp;strhelper&nbsp;=&nbsp;new&nbsp;person (); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string&nbsp;r1&nbsp;=&nbsp;strhelper.processfunc ("Chinese,&nbsp;")
Hello ", &nbsp;new&nbsp;mydelegate (Strhelper.chinesesayhello)); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string&nbsp;r2&nbsp;=&nbsp;strhelper.processfunc ("中文版",
&nbsp; "Hello", &nbsp;new&nbsp;mydelegate (Strhelper.englishsayhello); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string&nbsp;r3&nbsp;=&nbsp;strhelper.processfunc ("Japanese",
&nbsp; "こんにちは", &nbsp;new&nbsp;mydelegate (Strhelper.japanesesayhello));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.writeline (R1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.writeline (R2); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.writeline (R3);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.readkey (); &NBSP;&NBSP;&NBSP;&NBSP} public&nbsp;delegate&nbsp;string&nbsp;mydelegate (string&nbsp;s1,&nbsp;string&nbsp;s2
); Public&nbsp;class&nbsp;person {&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;string&nbsp;processfunc (STRING&NBSP;S1, &nbsp;string&nbsp;s2,&nbsp;mydelegate&nbsp;process) &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;return&nbsp;process (S1,&NBSP;S2); &NBSP;&NBSP;&NBSP;&NBSP} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;string&nbsp;chinesesayhello (string&nbsp;s1,&nbsp; STRING&NBSP;S2) &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;s1&nbsp;+ "
, "+&nbsp;s2; &NBSP;&NBSP;&NBSP;&NBSP} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;string&nbsp;englishsayhello (string&nbsp;s1,&nbsp; STRING&NBSP;S2) &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;s1&nbsp;+
&nbsp; "," &nbsp;+&nbsp;s2; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;sTring&nbsp;japanesesayhello (STRING&NBSP;S1,&NBSP;STRING&NBSP;S2) &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;s1&nbsp;+ "," +&nbsp;s2; &NBSP;&NBSP;&NBSP;&NBSP}}


Get the result:


The public string Processfunc (string s1, string s2, mydelegate process) defines a callback function that can pass any one of the methods conforming to the delegate to the desired result. To look closely at this design is very similar to the factory design pattern, I simply constructed a factory:

Public&nbsp;class&nbsp;person {&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;virtual&nbsp;string&nbsp;sayhello (string &NBSP;S2) &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;s2; &nbsp;&nbsp; &NBSP;&NBSP}} public&nbsp;class&nbsp;chinese&nbsp;:&nbsp;person {&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;override &nbsp;string&nbsp;sayhello (STRING&NBSP;S2) &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;return&nbsp; "Chinese," &nbsp;+&nbsp;s2; &NBSP;&NBSP;&NBSP;&NBSP}} public&nbsp;class&nbsp;english&nbsp;:&nbsp;person {&nbsp;&nbsp;&nbsp;&nbsp;public &nbsp;override&nbsp;string&nbsp;sayhello (STRING&NBSP;S2) &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp; "中文版," &nbsp;+&nbsp;s2; &NBSP;&NBSP;&NBSP;&NBSP}} public&nbsp;class&nbsp;japanese&nbsp;:&nbsp;person {&nbsp;&nbsp;&nbsp;&nbsp;public &nbsp;override&nbsp;string&nbsp;sayhello (STRING&NBSP;S2) &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp; "Japanese," &nbsp;+&nbsp;s2; &NBSP;&NBSP;&NBSP;&NBSP}}//main function calls Class&nbsp;program {&nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;void&nbsp;main ( String[]&nbsp;args) &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;r1&nbsp;= &nbsp;getperson ("Hello").
SayHello ("Hello"); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;r2&nbsp;=&nbsp;getperson ("Hello").
SayHello ("Hello"); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;r3&nbsp;=&nbsp;getperson ("こんにちは").
SayHello ("こんにちは");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.writeline (R1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.writeline (R2);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.writeline (R3);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.readkey (); &NBSP;&NBSP;&NBSP;&NBSP} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;person&nbsp;getperson (string&nbsp; Strtype) &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp; (strtype&nbsp;==&nbsp; "Hello") &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Return&nbsp;new&nbsp;chinese (); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if&nbsp; (strtype&nbsp;==&nbsp; "Hello") &nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;new&nbsp;english (); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;return&nbsp;new&nbsp;japanese (); &NBSP;&NBSP;&NBSP;&NBSP} &nbsp;&nbsp;&nbsp;&nbsp;}


The results are the same as above:




Design Pattern Instances

This paper simply extracts several design patterns to be implemented according to polymorphism and delegate, of course, the focus here is not on design patterns, but in order to make readers better understand delegates. So many details of the design pattern may be skipped in this article.

A simple factory model: This article on the use of calculator examples to explain.

1, polymorphic implementation of simple factory model.

class&nbsp;program2 {&nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;void&nbsp;main (String[]&nbsp;args) &nbsp;&nbsp;&nbsp; &nbsp;{&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;//1. Using polymorphism to implement simple Factory mode &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;int&nbsp;x&nbsp;=&nbsp;8,&nbsp;y&nbsp;=&nbsp;2; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;ires1&nbsp;=&nbsp;getobject ("+").
Compute (X,&nbsp;y); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;ires2&nbsp;=&nbsp;getobject ("-").
Compute (X,&nbsp;y); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;ires3&nbsp;=&nbsp;getobject ("*").
Compute (X,&nbsp;y); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;ires4&nbsp;=&nbsp;getobject ("/").
Compute (X,&nbsp;y);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.writeline (IRES1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.writeline (IRes2);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.writeline (IRES3); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.wrIteline (IRES4);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.readkey (); &NBSP;&NBSP;&NBSP;&NBSP} &nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;calculator&nbsp;getobject (String&nbsp;type) &nbsp;
&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Calculator&nbsp;oRes&nbsp;=&nbsp;null; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch&nbsp; (type) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;{&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp; "+": &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ores&nbsp;=&nbsp;new
&nbsp;add ();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp; "-": &nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ores&nbsp;=&nbsp;new&nbsp;subtract (); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp; "*": &nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ores&nbsp;=&nbsp;new&nbsp;multiply ();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp; "/": &nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ores&nbsp;=&nbsp;new&nbsp;divide ();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;
ores; &NBSP;&NBSP;&NBSP;&NBSP}} public&nbsp;class&nbsp;calculator {&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;virtual&nbsp; Int&nbsp;compute (int&nbsp;x,&nbsp;int&nbsp;y) &nbsp;&nbsp; &nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0; &nbsp;&nbsp;&nbsp;&nbsp;} public &nbsp;class&nbsp;add&nbsp;:&nbsp;calculator {&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;override&nbsp;int&nbsp;compute (int&nbsp;x,&nbsp;int&nbsp;y) &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return
&nbsp;x&nbsp;+&nbsp;y; &NBSP;&NBSP;&NBSP;&NBSP}} public&nbsp;class&nbsp;subtract&nbsp;:&nbsp;calculator {&nbsp;&nbsp;&nbsp;&nbsp; Public&nbsp;override&nbsp;int&nbsp;compute (int&nbsp;x,&nbsp;int&nbsp;y) &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;x&nbsp;-&nbsp;y; &NBSP;&NBSP;&NBSP;&NBSP}} public&nbsp;class&nbsp;multiply&nbsp;:&nbsp;calculator {&nbsp;&nbsp;&nbsp;&nbsp; Public&nbsp;override&nbsp;int&nbsp;compute (int&nbsp;x,&nbsp;int&nbsp;y) &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;x&nbsp;*&nbsp;y; &NBSP;&NBSP;&NBSP;&NBSP}} PUBLIC&NBSP;CLASS&NBSP;DIVIDE&NBSP;:&NBSP;CALCULator {&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;override&nbsp;int&nbsp;compute (int&nbsp;x,&nbsp;int&nbsp;y) &nbsp; &nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp; (y&nbsp;==&nbsp;0) &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return&nbsp;0; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;x
&nbsp;/&nbsp;y; &NBSP;&NBSP;&NBSP;&NBSP}}

The


code should be easy to read and be implemented directly by rewriting the method, which is not explained too much.

2, the delegate method implements the simple factory pattern.

class&nbsp;program2 {&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;void&nbsp;main (string[]&nbsp; args) &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #region &nbsp;2. Delegates implement simple Factory mode &nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;x&nbsp;=&nbsp;8,&nbsp;y&nbsp;=&nbsp;2;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;ocalculator&nbsp;=&nbsp;new&nbsp;calculator (); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;ires1&nbsp;=&nbsp;ocalculator.compute (X,&nbsp;y, &nbsp;ocalculator.add)//Pass the method as a parameter &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;iRes2&nbsp;=&nbsp;
Ocalculator.compute (x,&nbsp;y,&nbsp;ocalculator.subtract); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;ires3&nbsp;=&nbsp;ocalculator.compute (X,&nbsp;y,
&nbsp;ocalculator.multiply); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;ires4&nbsp;=&nbsp;ocalculator.compute (X,&nbsp;y,
&nbsp;ocalculator.divide); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;console.writeline (IRES1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.writeline (IRes2);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.writeline (IRES3); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.writeline (iRes4);&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; #endregion &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.readkey ();
&NBSP;&NBSP;&NBSP;&NBSP} public&nbsp;delegate&nbsp;int&nbsp;delegatecalculator (Int&nbsp;x,&nbsp;int&nbsp;y); Public&nbsp;class&nbsp;calculator {&nbsp;//passes an instance of the method in and executes it in the Compute method &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;int
&nbsp;compute (Int&nbsp;x,&nbsp;int&nbsp;y,&nbsp;delegatecalculator&nbsp;calculator) &nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;calculator (X,&nbsp;y); &NBSP;&NBSP;&NBSP;&NBSP} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;int&nbsp;add (int&nbsp;x,&nbsp;int&nbsp;y) &nbsp; &nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;x&nbsp;+&nbsp;y;
&NBSP;&NBSP;&NBSP;&NBSP} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;int&nbsp;subtract (Int&nbsp;x,&nbsp;int&nbsp;y) &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;x&nbsp;-&nbsp;y; &nbsp; &NBSP;&NBSP;&NBSP} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;int&nbsp;multiply (int&nbsp;x,&nbsp;int&nbsp;y) &nbsp; &nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;x&nbsp;*&nbsp;y; &nbsp;&nbsp; &NBSP;&NBSP} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;int&nbsp;divide (int&nbsp;x,&nbsp;int&nbsp;y) &nbsp;&nbsp; &nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp; (y&nbsp;==&nbsp;0) &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return
&nbsp;0; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;x
&nbsp;/&nbsp;y; &NBSP;&NBSP;&NBSP;&NBSP}}


Here you need to define four implementation methods add, subtract, Multiply, Divide, regardless of which class the four methods are under, as long as the parameters and return values of the four methods are consistent with the definition of the delegate. This also validates the above saying "stand at the level of the method, a very useful feature of a delegate instance is that it neither knows nor cares about the details of the class to which it encapsulates the method, and it is most important for it to be compatible with the parameters and return values of the delegate. The results are the same in both ways:



Ii. Observer Pattern: The most typical scenario for observer mode is the scene of subscribers and subscription numbers

1, a pure polymorphic way to implement the Observer mode: This code is very much inside the garden.

CLASS&NBSP;PROGRAM3 {&nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;void&nbsp;main (String[]&nbsp;args) &nbsp;&nbsp;&nbsp; &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp; Specific theme roles are usually implemented with specific intrusion &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;concretesubject&nbsp;subject&nbsp;=&nbsp;new&nbsp;concretesubject (); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;subject.
Attach (New&nbsp;concreteobserver (subject,&nbsp; "Observer&nbsp;a")); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;subject.
Attach (New&nbsp;concreteobserver (subject,&nbsp; "observer&nbsp;b")); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;subject.
Attach (New&nbsp;concreteobserver (subject,&nbsp; "observer&nbsp;c")); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;subject.
subjectstate&nbsp;=&nbsp; "Ready"; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;subject.
Notify ();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.read (); &NBSP;&NBSP;&NBSP;&NBSP}//Abstract subject class Public&nbsp;abstract&nbsp;class&nbsp;subject {&nbsp;&nbsp;&nbsP;&nbsp;private&nbsp;ilist&lt;observer&gt;&nbsp;observers&nbsp;=&nbsp;new&nbsp;list&lt;observer&gt; (); &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;summary&gt; &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp; Add Observer &nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&lt;/summary&gt; &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;param&nbsp;name= "Observer" &gt;&lt;/param&gt; &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;attach (observer&nbsp;observer) &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;observers.
ADD (Observer); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;summary&gt; &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp; Remove Observer &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;/summary&gt; &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;param&nbsp;name= " Observer "&gt;&lt;/param&gt; &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;detach (observer&nbsp;observer) &nbsp; &nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;observers.
REMOVE (Observer); &NBSP;&NBSP;&NBSP;&NBSP} &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;summary&gt; &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp; notices to observers &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;/summary&gt; &nbsp;&nbsp;&nbsp; &nbsp;public&nbsp;void&nbsp;notify () &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach&nbsp; (observer&nbsp;o&nbsp;in&nbsp;observers) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;o.update (); &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP} &nbsp;&nbsp;&nbsp;&nbsp;}//Specific topic class public&nbsp;class&nbsp; Concretesubject&nbsp;:&nbsp;subject {&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;string&nbsp;subjectState; &nbsp;&nbsp; &nbsp;&nbsp;///&nbsp;&lt;summary&gt; &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp; specific observer status &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp; &lt;/summary&gt; &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;string&nbsp;subjectstate &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;get&nbsp;{&nbsp;return&nbsp;subjectstate;&nbsp;} &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set&nbSp {&nbsp;subjectstate&nbsp;=&nbsp;value;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp}}//abstract Observer class Public&nbsp;abstract&nbsp;class &nbsp;observer {&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;abstract&nbsp;void&nbsp;update ();}//Specific observer Public&nbsp;class
&nbsp;concreteobserver&nbsp;:&nbsp;observer {&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;string&nbsp;observerState;
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;string&nbsp;name;
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ConcreteSubject&nbsp;subject; &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;summary&gt; &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp; specific observer with a specific theme to implement &nbsp;&nbsp; &nbsp;&nbsp;///&nbsp;&lt;/summary&gt; &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;concretesubject&nbsp;subject &nbsp;
&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;get&nbsp;{&nbsp;return&nbsp;subject;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set&nbsp;{&nbsp;subject&nbsp;=&nbsp;value;&nbsp;} &nbsp;&nbsp; &NBSP;&NBSP} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;concreteobserver (Concretesubject&nbsp;subject,&nbsp;string&nbsp;name) &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.subject
&nbsp;=&nbsp;subject;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.name&nbsp;=&nbsp;name; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;summary&gt; &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp; Implement update operations &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;/summary&gt; &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;override for abstract observers &nbsp;void&nbsp;update () &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;observerstate &nbsp;=&nbsp;subject.
Subjectstate; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.writeline ("The&nbsp;observer ' s&nbsp;state&nbsp;of
&nbsp;{0}&nbsp;is&nbsp;{1} ", &nbsp;name,&nbsp;observerstate); &NBSP;&NBSP;&NBSP;&NBSP} You can see that although the separation between the observer observer&nbsp; and the subject subject is well achieved. But there was a call to the observer in subject's interior: Public&nbsp;void&nbsp;notify () {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach&nbsp; (Observer &nbsp;o&nbsp;in&nbsp;observers) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&NBSP;&NBSP;&NBSp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;o.update (); &NBSP;&NBSP;&NBSP;&NBSP;&NBSP}}



2, polymorphism, and delegates implement the observer pattern.

CLASS&NBSP;PROGRAM3 {&nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;void&nbsp;main (String[]&nbsp;args) &nbsp;&nbsp;&nbsp; &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp; Specific theme roles are usually implemented with specific intrusion &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;concretesubject&nbsp;subject&nbsp;=&nbsp;new&nbsp;concretesubject ();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//incoming is just the way the observer passes. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;subject. Attach (New&nbsp;concreteobserver (subject,&nbsp; "Observer&nbsp;a").
Update); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;subject. Attach (New&nbsp;concreteobserver (subject,&nbsp; "Observer&nbsp;b").
Update); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;subject. Attach (New&nbsp;concreteobserver (subject,&nbsp; "Observer&nbsp;c").
Update); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;subject.
subjectstate&nbsp;=&nbsp; "Ready"; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;subject.
Notify ();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.read (); &nbsp;&nbsp;&NBSP;&NBSP}} public&nbsp;delegate&nbsp;void&nbsp;observerdelegate (); Abstract Theme class Public&nbsp;abstract&nbsp;class&nbsp;subject {&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;ObserverDelegate&nbsp;
Observedelegate; &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;summary&gt; &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp; Add Observer &nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&lt;/summary&gt; &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;param&nbsp;name= "Observer" &gt;&lt;/param&gt;
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;attach (Observerdelegate&nbsp;observer) &nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;observedelegate&nbsp;+=&nbsp;observer; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;summary&gt; &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp; Remove Observer &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;/summary&gt; &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;param&nbsp;name= " Observer "&gt;&lt;/param&gt; &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;detach (observerdelegate&nbsp;observer ) &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;observedelegate&nbsp;-=&nbsp;observer; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;summary&gt; &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp; Give notice to the Observer &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;/summary&gt; &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp; Notify () &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp; (observedelegate &nbsp;!=&nbsp;null) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;observedelegate (); &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP} &nbsp;&nbsp;&nbsp;&nbsp;}//Specific topic class public&nbsp;class&nbsp; Concretesubject&nbsp;:&nbsp;subject {&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;string&nbsp;subjectState; &nbsp;&nbsp; &nbsp;&nbsp;///&nbsp;&lt;summary&gt; &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp; specific observer status &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp; &lt;/summary&gt; &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;string&nbsp;subjectstate &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;get&nbsp;{&nbsp;return&nbsp;subjectstate;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;set&nbsp;{&nbsp;subjectstate&nbsp;=&nbsp;value;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp}}//
Specific Observer Public&nbsp;class&nbsp;concreteobserver {&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;string&nbsp;observerState;
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;string&nbsp;name;
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ConcreteSubject&nbsp;subject; &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;summary&gt; &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp; specific observer with a specific theme to implement &nbsp;&nbsp; &nbsp;&nbsp;///&nbsp;&lt;/summary&gt; &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;concretesubject&nbsp;subject &nbsp;
&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;get&nbsp;{&nbsp;return&nbsp;subject;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set&nbsp;{&nbsp;subject&nbsp;=&nbsp;value;&nbsp;} &nbsp;&nbsp; &NBSP;&NBSP} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;concreteobserver (CONCRETESUBJECT&NBSP;SUBJECT,&NBSP;STRING&NBsp;name) &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.subject&nbsp;=&nbsp;
Subject
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.name&nbsp;=&nbsp;name; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;summary&gt; &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp; Implementation of update operations in abstract observers &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;/summary&gt; &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp; Update () &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;observerState&nbsp;=&nbsp; Subject.
Subjectstate; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.writeline ("The&nbsp;observer ' s&nbsp;state&nbsp;of
&nbsp;{0}&nbsp;is&nbsp;{1} ", &nbsp;name,&nbsp;observerstate); &NBSP;&NBSP;&NBSP;&NBSP}}



Get the result:


Advantages of this design:

(1) The method update of the notification is passed to the subject object in the form of a delegate. This subject object subject is completely isolated from the observer. Better implementation of low coupling.
(2) reduced the definition of the observer abstract class. Make the whole design more streamlined.
(3) If the design is further developed, the observer here customizes the Delegate void Observerdelegate () method of this type. For example, you need to follow the update () method to record the operation of a log. Such as:


Specific Observer Public&nbsp;class&nbsp;concreteobserver {&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;string&nbsp;observerState;
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;string&nbsp;name;
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ConcreteSubject&nbsp;subject; &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;summary&gt; &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp; specific observer with a specific theme to implement &nbsp;&nbsp; &nbsp;&nbsp;///&nbsp;&lt;/summary&gt; &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;concretesubject&nbsp;subject &nbsp;
&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;get&nbsp;{&nbsp;return&nbsp;subject;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set&nbsp;{&nbsp;subject&nbsp;=&nbsp;value;&nbsp;} &nbsp;&nbsp; &NBSP;&NBSP} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;concreteobserver (concretesubject&nbsp;subject,&nbsp;string &nbsp;name) &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.subject&nbsp;=&nbsp;
Subject
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.name&nbsp;=&nbsp;name; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;summary&gt; &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp; Implementing update operations in abstract observers &nbsp;&nbsp; &nbsp;&nbsp;///&nbsp;&lt;/summary&gt; &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;update () &nbsp;&nbsp;&nbsp; &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;observerstate&nbsp;=&nbsp;subject.
Subjectstate; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.writeline ("The&nbsp;observer ' s&nbsp;state&nbsp;of
&nbsp;{0}&nbsp;is&nbsp;{1} ", &nbsp;name,&nbsp;observerstate); &NBSP;&NBSP;&NBSP;&NBSP} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;log () &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.writeline ("Log:update Method execution completed"); &NBSP;&NBSP;&NBSP;&NBSP}}



Then the log method can only be passed in as a delegate when the client invokes:

static void Main (string[] args)
{
//specific theme roles are usually implemented in a specific
concretesubject subject = new ConcreteSubject ();
//Incoming is just an observer's way of passing.    
var obj = new Concreteobserver (subject, "Observer A");
Subject. Attach (obj.    Update);
Subject. Attach (obj.    LOG);
Subject.    Subjectstate = "Ready";
Subject.    Notify ();
Console.read ();
}


is not a little more flexible. In the case of pure polymorphism, the code changes much more when the log method is needed, as the subject specifies the call Update () method.


Third, the template method model, here take the equipment collection as an example to explain:

1, polymorphic Implementation Template method pattern:

class&nbsp;program4 {&nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;void&nbsp;main (String[]&nbsp;args) &nbsp;&nbsp;&nbsp; &nbsp;{&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;VAR&NBSP;OTEM1&NBSP;=&NBSP;NEW&NBSP;DEVICEMML () &nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;otem1.spider ();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.writeline ("");
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;VAR&NBSP;OTEM2&NBSP;=&NBSP;NEW&NBSP;DEVICETL2 ();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;otem2.spider ();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.readkey (); &NBSP;&NBSP;&NBSP;&NBSP}} public&nbsp;abstract&nbsp;class&nbsp;templetedevice {&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;
Template methods, do not define templates as virtual or abstract methods, avoid quilt overrides, and prevent changes in the order in which processes are executed &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;spider () &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.writeline ("Start of equipment Acquisition"); &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.
Login (); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbSp;&nbsp;&nbsp;this.
Validation (); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.
SpiderByType1 (); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.
SpiderByType2 (); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.
Loginout ();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.writeline ("Equipment collection End"); &NBSP;&NBSP;&NBSP;&NBSP} &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp; Landing &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;login () &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.writeline ("Landing"); &nbsp; &NBSP;&NBSP;&NBSP} &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp; Verify &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;validation ( ) &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.writeline ("Validation"); &nbsp;&nbsp; &nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp; Collection &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;abstract&nbsp;void&nbsp;
SpiderByType1 ();
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;abstract&nbsp;void&nbsp;spiderbytype2 (); &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp; Cancellation &Nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;loginout () &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;console.writeline ("cancellation"); &NBSP;&NBSP;&NBSP;&NBSP}}//MML type of device collection Public&nbsp;class&nbsp;devicemml&nbsp;:&nbsp;templetedevice {&nbsp; &nbsp;&nbsp;&nbsp;public&nbsp;override&nbsp;void&nbsp;spiderbytype1 () &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.writeline ("MML type equipment began to collect 1"); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//... &nbsp;&nbsp;&nbsp;&nbsp} &nbsp;&nbsp;&nbsp;&nbsp; Public&nbsp;override&nbsp;void&nbsp;spiderbytype2 () &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;console.writeline ("MML type equipment began to collect 2"); &NBSP;&NBSP;&NBSP;&NBSP}}//TL2 type Device collection Public&nbsp;class&nbsp;devicetl2&nbsp;:&nbsp;templetedevice {&nbsp;&nbsp; &nbsp;&nbsp;public&nbsp;override&nbsp;void&nbsp;spiderbytype1 () &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.writeline ("TL2 type equipment began to collect 1");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//... &nbsp;&nbsp;&nbsp;&nbsp} &nbsp;&nbsp;&nbsp;&nbsp; Public&nbsp;override&nbsp;void&nbsp;spiderbytype2 () &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;console.writeline ("TL2 type equipment began to collect 2"); &NBSP;&NBSP;&NBSP;&NBSP}}

Non-abstract methods within the


Parent class are template methods, which are common to subclasses and cannot be overridden. SpiderType1 and SpiderType2 are methods that require subclass overrides. Template method Patterns define the implementation steps of an algorithm in an abstract class, defer implementation of these steps to a specific subclass, so that all subclasses reuse the code of the parent class, so the template method pattern is a technique for implementing code reuse based on inheritance.


2, after using a delegate rewrite:

class&nbsp;program4 {&nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;void&nbsp;main (String[]&nbsp;args) &nbsp;&nbsp;&nbsp; &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;otem1&nbsp;=&nbsp;new&nbsp;templetedevice (
DEVICEMML.SPIDERBYTYPE1,&NBSP;DEVICEMML.SPIDERBYTYPE2);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;otem1.spider ();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.writeline (""); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;otem2&nbsp;=&nbsp;new&nbsp;templetedevice (
DEVICETL2.SPIDERBYTYPE1,&NBSP;DEVICETL2.SPIDERBYTYPE2);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;otem2.spider ();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.readline ();
&NBSP;&NBSP;&NBSP;&NBSP}} public&nbsp;delegate&nbsp;void&nbsp;devicedelegate (); Public&nbsp;class&nbsp;templetedevice {&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;DeviceDelegate&nbsp;oDelegate; &nbsp; &nbsp;&nbsp;&nbsp;public&nbsp;templetedevice (Params&nbsp;devicedelegate[]&nbsp;lstfunc) &NBSP;&NBSP;&NBSP;&NBSp {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach&nbsp; (Var&nbsp;ofunc&nbsp;in&nbsp;lstfunc) &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;oDelegate&nbsp;+=&nbsp;oFunc; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &NBSP;&NBSP} &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp; template methods, do not define templates as virtual or abstract methods, avoid quilt overrides, and prevent changes in the order in which processes are executed &nbsp;&nbsp; &nbsp;&nbsp;public&nbsp;void&nbsp;spider () &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;console.writeline ("Equipment acquisition start"); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.
Login (); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.
Validation (); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp; (odelegate&nbsp;!=&nbsp;null) &nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;odelegate (); &nbsp;&nbsp;&nbsp;&nbsp;&NBSP;&NBSP;&NBSP;&NBSP} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.
Loginout ();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.writeline ("Equipment collection End"); &NBSP;&NBSP;&NBSP;&NBSP} &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp; Landing &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;login () &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.writeline ("Landing"); &nbsp; &NBSP;&NBSP;&NBSP} &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp; Verify &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;validation ( ) &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.writeline ("Validation"); &nbsp;&nbsp; &NBSP;&NBSP} &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp; Logoff &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;loginout () &nbsp; &nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.writeline ("Logoff"); &nbsp;&nbsp;&nbsp; &NBSP}}//MML type of device collection PUBLIC&NBSP;CLASS&NBSP;DEVICEMML {&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;void &nbsp;spiderbytype1 () &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.writeline ("MML type equipment began to collect 1"); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//... &nbsp;&nbsp;&nbsp;&nbsp} &nbsp;&nbsp;&nbsp;&nbsp; Public&nbsp;static&nbsp;void&nbsp;spiderbytype2 () &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;console.writeline ("MML type equipment began to collect 2"); &NBSP;&NBSP;&NBSP;&NBSP}}

Collection of TL2 type equipment
public class DeviceTL2
{
public static void SpiderByType1 ()
{
Console.WriteLine ("TL2 type equipment began to collect 1");
//.......
}

public static void SpiderByType2 ()
{
Console.WriteLine ("TL2 type equipment began to collect 2");
}
}


Get the result:


The significance of optimizing template method Patterns:

(1) The inheritance relationship between subclass and parent class is lifted, and the low coupling between objects is better realized.

(2) The use of delegates can dynamically implement the combination of methods, this way more flexible, subclasses can be more flexible design of different parts of the method. The number of methods is then passed through the params, with no strict restrictions on the number of methods.


Of course, other design patterns can also be commissioned to optimize the design, bloggers here temporarily only share the similarities and differences of these three patterns. In general, delegates are unlikely to replace polymorphism to implement various patterns, but they can be combined with polymorphism to achieve a more flexible design. Through these two articles down, do not know whether you have a feeling of the delegate, commissioned this thing, heavy in combat, like swimming, if not so many times, you can never learn. The above is only the personal understanding of bloggers, may be a lot of convenience is not considered so comprehensive, I hope you will correct me.

Related Article

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.