2012-03-29 14 views
4

Szenario: ein Spiel mit einem Brett und mehrere Fliesen darauf. Klassen: Board, Tile, Spieler und natürlich Spiel. Jedes Mal, wenn der Spieler eine Fliese drückt, seine Punktzahl von 1. Vorstand erhöht wird innerhalb von Spiel, und eine Reihe von Tile innerhalb von Vorstand instanziiert instanziiert. Meine erste Option, diese Punktzahl leicht zu erhöhen, war eine öffentliche statische Klasse mit einem öffentlichen statischen Feld (Score) zu machen. Natürlich ist es eher amateurhaft. Und schien den gesamten Fluss der App zu durchbrechen.C# Delegierte und Veranstaltungen Design/Architektur

Nach einigem Nachdenken änderte ich alles, um Ereignisse zu verwenden; Tile löst ein Ereignis beim Klicken auf; Board behandelt dieses Ereignis und löst ein weiteres Ereignis in der Hauptklasse Game Klasse aus. Spieler wird innerhalb von Spiel instanziiert; Wenn Spiel behandelt das Ereignis erhalten von Board, es tut ein PlayerOne (Instanz Player) .Score + = 1;

Soll ich einfach weitermachen und diesen Fluss verwenden? Haben Sie andere Architektur-/Design-Ideen, die besser funktionieren würden? Warum würden deine Ideen besser funktionieren? Ich habe vorher keine speziell angefertigten Events verwendet und ich denke, dass das ganze Event, das eine weitere, gleichgültige Idee aufwirft, ein bisschen falsch ist. Aus der Ferne sieht es jedoch nach einem guten Fluss aus. Und es macht die Arbeit richtig.

Antwort

0

Sie sollten etwas Code zur Verfügung gestellt haben.

Soll ich einfach weitermachen und diesen Fluss verwenden?

Hängt davon ab, wie die Ereignisse aussehen.

Haben Sie andere Architektur/Design-Ideen, die besser funktionieren würden?

Veröffentlichen/Abonnieren ist eine Alternative. Aber die .NET-Ereignisse funktionieren hier gut.

Ich habe keine maßgeschneiderten Veranstaltungen zuvor intensiv genutzt und ich denke, dass das ganze Ereignis, das eine andere, sogar eine Idee aufwirft, ein bisschen falsch ist.

Es ist in Ordnung, Kapselung zu halten. Ich würde etwas tun wie:

class Tile 
{ 
    public event EventHandler Clicked = delegate{}; 
} 

class Board 
{ 
    private void OnTileClick(object source, EventArgs e) 
    { 
     var tile = (Tile)source; 
     //doSome 

     var args = new CustomEventArgs(); 
     CustomEvent(this, args); 
    } 

    public event EventHandler<CustomEventArgs> SomeEvent = delegate{}; 
} 

public class SomeCustomEventArgs : EventArgs 
{ 
} 
+0

In der Tat, sollte etwas Code gepostet haben; Trotzdem hat dein Code geholfen: es macht viel mehr Sinn, die Animation des Plättchens vom Spielfeld aus aufzurufen, da das Brett die Plättchen "verwaltet". Vorher würde ich zuerst die Animation über die Klasse der Kachel starten und dann würde ich das TilePress-Ereignis zum Board bringen. –

+0

Hier finden Sie einige gute Antworten; besonders diejenigen über das Beobachtermuster (jetzt weiß ich, was ich mein Experiment nennen soll). Leider kann ich nur eins wählen. Ich denke, ich werde deine auswählen, weil der Code auch geholfen hat. –

0

Die einzige andere Möglichkeit, die mir in den Sinn kommt, ist das Übergeben/Setzen von Delegaten höherer Klassen, die als Callbacks fungieren - so können die unteren Klassen nach einem gültigen Delegierten suchen und ihn ohne Wissen darüber, wem er gehört, aufrufen. Wenn Sie eine Liste möglicher Delegierter erstellen, können mehrere Abonnenten von diesem Rückruf profitieren.

Nachdem gesagt, finde ich Ihre Event-Architektur ziemlich elegant.

1

Das, was Sie beschrieben haben, sieht wie das Observer Designmuster aus. Das Spiel sollte auf Ereignisse vom Brett "hören", das Brett sollte zu den Ereignissen von den Fliesen etc. hören.

0

Eine andere Weise, es anzusehen ist, dass das Brett vom Spieler abhängt, um richtig zu funktionieren. Wie viele Spieler gibt es gleichzeitig und werden Spieler während der Spielzeit zum und vom Brett hinzugefügt?

Wenn nicht, können Sie möglicherweise den oder die Spieler beim Erstellen an das Board übergeben, und dann könnte das Board den Spielerstand erhöhen. Dies funktioniert, solange es keine andere Logik gibt, die auf der Spiel-Ebene passiert und die Wertung beeinflussen könnte.

0

Die Architektur, die Sie implementiert scheinen, funktioniert gut für dieses Szenario.

Mithilfe der Observer-Architektur können die Abhängigkeiten, die Sie über die Objektbeziehungen erstellt haben, einfach verwaltet werden.

Die Architektur des Beobachters ermöglicht es Ihnen, Spieler, Kacheln und Boards ganz einfach hinzuzufügen oder zu entfernen. Wenn es ein Erfordernis für ein "Spiel" gibt, jetzt mehrere Boards zu verwalten, dann können Sie das Objekt einfach hinzufügen und den exponierten Events abonnieren, um es elegant zu verwalten. Dies liegt daran, dass eine Kachel nicht wissen muss, dass ein Spieler existiert. Genauso wie ein Spieler nicht wissen muss, dass ein Spiel existiert - er macht seine Arbeit unabhängig.

Andere Muster können unerwünschte Abhängigkeiten erzeugen, die zu dem zusätzlichen Code führen, der erforderlich wäre, um die Informationen in der Kette (von Kacheln, Spielern, Spielen) weiterzuleiten - dies könnte sehr leicht zu Problemen führen Ihrer Projektumsetzung.