2009-04-21 2 views
1

Ich brauche Hilfe versuchen, das Beobachtermuster und die Delegaten zu verstehen. Ich habe diesen Code auf einer anderen Website gefunden und versuche zu verstehen, was er eigentlich macht. Kann mir jemand helfen?Observer Pattern und Delegates

Wenn ich den Code ausführen, bekomme ich beide Meldungen "Server läuft" und "Server ist ausgefallen, wir arbeiten daran, es wird bald wieder da sein". Ich glaube, ich bekomme beide Nachrichten, weil es im Main einen Server gibt. Server_status = true; und ein server.ServerStatus = false. Allerdings, wenn ich den Server auskommentieren. ServerStatus = true; und renne dann ich bekomme die Meldung "Server läuft und läuft" aber ich erwartete nur zu sehen "Server ist ausgefallen, wir arbeiten daran es wird bald wieder kommen.". Kann jemand das erklären? Susan

class Program 
{ 
    static void Main(string[] args) 
    { 
     Server server = new Server(); 
     server.ServerStatusChanged += new EventHandler(ProcessServerStatus); 
     server.ServerStatus = true; 
     server.ServerStatus = false; 
     Console.Read(); 
    } 


    public class Server 
    { 
     public event EventHandler ServerStatusChanged; 
     private bool _ServerStatus; 

     public bool ServerStatus 
     { 
      get { return this._ServerStatus; } 
      set { 
       if (this._ServerStatus == value) return; // Dont need to do anything; 
       if (this.ServerStatusChanged != null) // make sure the invocation list is not empty 
        ServerStatusChanged(value, new EventArgs()); // Firing Event 
       this._ServerStatus = value; 
      } 
     } 
    } 



    public static void ProcessServerStatus(object sender, EventArgs e) 
    { 
     bool status = (bool)sender; 
     if (status) 
      Console.WriteLine("Server is up and running"); 
     else 
      Console.WriteLine("Server is down, We are working on it it will be back soon"); 

    } 



} 
+1

Dies ist getaggt Java, aber ich denke, der Code ist eigentlich C#. –

+0

In der Tat ist es, dass diese {} set {}: s C# 's Feature sind, nicht Javas. Geänderte Tags – Esko

Antwort

0

Dies ist ein Ereignis Registrierung ...

server.ServerStatusChanged += new EventHandler(ProcessServerStatus); 

Er sagt: "wenn es ein ServerStatusChanged ist, wobei das Verfahren ProcesServerStatus nennen." Wenn Sie also ServerStatus auf "true" setzen, erhalten Sie einen Aufruf von ProcessServerStatus, der "true" und "Server is up ..." ausgibt. Wenn Sie es in false ändern, wird ein anderes Ereignis ausgelöst, aber dieses Mal ist ServerStatus false, Sie erhalten also "Server is down ...". Sie beobachten also den Serverstatus und machen etwas (ProcessServerStatus), wenn er sich ändert.

0

Im Wesentlichen tritt auf, dass die Zuordnungen, die Sie in Main haben, die ServerStatus auf true/false festlegen, die Funktion "set" der ServerStatus-Eigenschaft aufrufen.

Innerhalb dieser Funktion wird ein Ereignis erstellt und an den ServerStatusChanged-Handler gesendet, der von jedem empfangen wird, der sich für Ereignisse registriert hat. Beachten Sie außerdem, dass das Ereignis nur ausgelöst wird, wenn sich der Status ändert.

In diesem Fall Main, für das Ereignis in der

Server.ServerStatusChanged += new EventHandler(ProcessServerStatus); 

Linie

registriert.

Da Sie ServerStatus auf "true" und dann auf "false" in Main setzen, werden zwei Ereignisse ausgelöst, die dazu führen, dass auf der Konsole sowohl "Server läuft" als auch "Server läuft" angezeigt wird. "

2

Hier ist Code, der das tut, was Sie wollen.

Beachten Sie die Variable _initialized. Dies wird benötigt, da sonst beim ersten Mal nichts passiert. Sie müssten den Status auf "True" setzen, bevor er ordnungsgemäß funktioniert.

Auch ich, was Sie beschreiben, ist nicht für mich passiert. Ich habe nicht die Nachricht erhalten, dass es läuft. Ich habe überhaupt nichts bekommen.

class Program 
{ 
    static void Main(string[] args) 
    { 
     Server server = new Server(); 
     server.ServerStatusChanged += new EventHandler(ProcessServerStatus); 
     //server.ServerStatus = true; 
     server.ServerStatus = false; 
     Console.Read(); 
    } 

    public class Server 
    { 
     public event EventHandler ServerStatusChanged; 
     private bool _ServerStatus = false; 
     private bool _initialized = false; 
     public bool ServerStatus 
     { 
      get { return this._ServerStatus; } 
      set 
      { 
       if (this._initialized == true && this._ServerStatus == value) 
        return; // Dont need to do anything;     
       else 
        this._initialized = true; 
       if (this.ServerStatusChanged != null) // make sure the invocation list is not empty      
        ServerStatusChanged(value, new EventArgs()); // Firing Event     
       this._ServerStatus = value; 
      } 
     } 
    } 
    public static void ProcessServerStatus(object sender, EventArgs e) 
    { 
     bool status = (bool)sender; 
     if (status) 
      Console.WriteLine("Server is up and running"); 
     else Console.WriteLine("Server is down, We are working on it it will be back soon"); 
    } 
} 
+0

Ohne den ServerStatus-Wert zu initialisieren, haben Sie wahrscheinlich unvorhersehbare Ergebnisse erhalten, d. H. "Server läuft ..." und weil der Setter die ProcessServerStatus-Methode nur bedingt aufruft, erhielten Sie nicht die Meldung "SErver is down ..." – simon

0

Wenn Sie nicht, bevor er über die Beobachter-Muster gekommen sind, könnte es instinktiv zu denken, dass alle Methodenaufrufe ziemlich statisch gemacht werden - die Methoden, die wir in unserem Code nennen sind das, was genannt wird. Mit dem Beobachtermuster können Sie jedoch dynamischer arbeiten. Du kannst etwas zur Laufzeit sagen "Hey, wenn das und das passiert, lass es mich wissen! Du kannst mich wissen lassen, indem du die eine oder andere Methode nennst" Der Beobachtete hält eine Aufzeichnung von jedem, der zu ihm gesagt hat Und das passiert, lass es mich wissen "- und dann, wenn es passiert, macht es genau das - lasst sie alle wissen. Dies geschieht, indem eine Liste der Methoden geführt wird, die aufgerufen werden müssen, und dann alle aufgerufen werden, wenn das Ereignis "ausgelöst" wird.

Die Linie:

server.ServerStatusChanged += new EventHandler(ProcessServerStatus); 

wird das Server-Objekt zu sagen: „Hey, wenn der Server-Status geändert wird, lassen Sie mich wissen, Sie können mir die ProcessServerStatus Methode durch Aufruf wissen lassen.“. Und so, wenn die Zeile:

server.ServerStatus = true; 

ausgeführt wird, löst es das ServerStatusChanged Ereignis, das dann alles aufruft, die gesagt hat, „lassen Sie mich wissen“. So wird es die ProcessServerStatus Methode aufrufen, da das die einzige Methode in seiner Liste ist.

Jede Methode in dieser Liste muss eine bestimmte Methodensignatur aufweisen. in diesem Fall void ProcessServerStatus(object sender, EventArgs e). Der sender Parameter ist in diesem Fall der Server-Status - Sie dies in der Zeile sehen:

ServerStatusChanged(value, new EventArgs()); 

Und so, wenn ProcessServerStatus genannt wird, wirft er es so ein Boolescher Wert, und druckt die entsprechende Zeichenfolge.

Wenn ich diesen Code ausführen, funktioniert es wie erwartet - wenn ich die serverStatus = true; Zeile auskommentieren, druckt es nichts (seit _serverStatus standardmäßig auf false, und das Ereignis wird nicht ausgelöst, wenn der Status nicht geändert wurde). Stattdessen, wenn ich die serverStatus = false; Zeile auskommentieren, sagt es "der Server ist und läuft"