2013-04-01 5 views
5

Ich bin nicht ganz sicher, wie man diese Frage in einem Satz formuliert, so dass ich Schwierigkeiten hatte, vorherige Beiträge zu suchen. Dies kommt häufig für mich und ich würde gerne einen Konsens darüber, wie man es angehen.Wann ich den Zustand eines Objekts überprüfen soll, allgemeine OOP, Beispiel in C#

Angenommen, Sie haben zwei Klassen, ExampleClass und ExampleClassManager. ExampleClass hat eine Update(Data data) Methode, die von ExampleClassManager aufgerufen wird. es will ExampleClass kann jedoch in einem von zwei Zuständen, und im Enabled Zustand sein, die data, um es verarbeiten in Update vergangen, und im Behinderten Zustand ist es nicht mit den data überhaupt nichts tun.

Soll ich für den Staat in der ExampleClassManager werden überprüft und nicht die data überhaupt vorbei, wenn es deaktiviert ist, oder sollte ich die data unabhängig und ignorieren es innerhalb ExampleClass passieren?

Hier ist ein Codebeispiel, falls ich es nicht klar artikulieren würde.

public class ExampleClass { 
    public bool Enabled { 
     get; 
     set; 
    } 

    public void Update(Data data) { 
     if(Enabled) { 
      //do stuff with data 
     } 
    } 
} 

public class ExampleClassManager { 
    private List<ExampleClass> exampleClassList=new List<ExampleClass>(); 

    public void UpdateList() { 
     foreach(ExampleClass exampleClass in exampleClassList) { 
      exampleClass.Update(data); 
     } 
    } 
} 

oder

public class ExampleClass { 
    public bool Enabled { 
     get; 
     set; 
    } 

    public void Update(Data data) { 
     //do stuff with data 
    } 
} 

public class ExampleClassManager { 
    private List<ExampleClass> exampleClassList=new List<ExampleClass>(); 

    public void UpdateList() { 
     foreach(ExampleClass exampleClass in exampleClassList) { 
      if(exampleClass.Enabled) { 
       exampleClass.Update(data); 
      } 
     } 
    } 
} 
+3

Nun, Fragen, die ich stellen würde, sind: A) Was passiert, wenn Sie eine deaktivierte 'ExampleClass'" aktualisiert ", dann diese Instanz aktiviert. Sollte es die Daten anzeigen, gegen die es gebunden war, bevor es deaktiviert wurde, oder sollte es die aktualisierten Daten anzeigen, die ihm bei seiner Deaktivierung zur Verfügung gestellt wurden? B) Ist der 'ExampleClassManager' _care_ ob 'ExampleClass' bei der Verteilung seiner Daten aktiviert ist? C) Erwarten Sie andere Implementierungen/Subklassen von 'ExampleClass', wo sie die Daten haben wollen oder andere" aktualisierbare "Konzepte haben, die sich ändern sollten, wenn sie" aktualisiert "sind, selbst wenn sie deaktiviert sind? –

+0

Auch D) Soll der Aufruf von Code Updates auf deaktivierten 'ExampleClass' Instanzen erzwingen? In Ihrem zweiten Beispiel kann der Aufruf-Code _ignore_ die Tatsache, dass eine Instanz deaktiviert ist und Änderungen daran erzwingen. Der gesamte Code einer Klasse, die "Update" aufruft, muss dann diesen Vertrag "Ich aktualisiere mich nicht, wenn ich deaktiviert bin" erfüllen, ist aber unter keiner Verpflichtung dazu. –

+1

Es hängt wirklich davon ab, wie wichtig die Verarbeitung der Eingabedaten ist. In diesem Szenario hat die 'ExampleClass' nicht ausgewählt, wie mit dem deaktivierten Zustand umzugehen ist, sondern es macht Clients diese Wahl. Du könntest dieses schlechte Design in Betracht ziehen. Es informiert Sie nicht, dass mit Ihrer Eingabe nichts passieren wird. Wenn die Verarbeitung Ihrer Daten durch 'ExampleClass' wichtig ist, sollten Sie nach diesem deaktivierten Zustand suchen. Wie reagieren Sie jedoch auf den entblößten Zustand? Eine Ausnahme auslösen? Ignorieren? Versuchen Sie eine andere Route? Etwas protokollieren? –

Antwort

3

Da es hängt von einer Eigenschaft von ExampleClass, würde ich die Option 1 und überprüfen innerhalb ExampleClass.Update wählen. Andernfalls könnte jedes Objekt mit Zugriff auf ein ExampleClass Objekt Updateungeachtet des Staates aufrufen. Indem Sie innerhalb der Update Methode überprüfen, stellen Sie sicher, dass es nur weitergeht, wenn das Objekt aktiviert ist. Die Frage ist, wer kann den Status des Objekts ändern?

Siehe Law of Demeter: nur für die aktuelle Einheit Einheiten „eng“ bezogen werden:

Jede Einheit nur begrenzte Kenntnisse über andere Einheiten haben sollte.

+0

Danke, das bringt eine verwandte Frage auf. Wenn ich eine Anzahl von ExampleClasses und einen ExampleClassManager habe, um sie zu verwalten, wäre es besser, "Enabled" als privat zu definieren und jede ExampleClass für ihren eigenen Status verantwortlich zu machen? Oder sollte ich "Enabled" zu einer öffentlichen Eigenschaft machen und den Manager veranlassen, die ExampleClass-Zustände zu setzen? In meinem vereinfachten Beispiel hängt es davon ab, wie die ExampleClass intern auf die an sie übergebenen "Data" -Objekte reagiert, ob "Enabled" wahr/falsch ist oder nicht. Ich habe vielleicht gerade meine eigene Frage mit dem letzten Satz beantwortet, aber bitte bestätigen Sie es. – tmakino

+0

Wenn jede ExampleClass vollständig für ihren eigenen Status verantwortlich ist, wird meine Managerklasse zu einem glorifizierten Dictionary , wobei int eine eindeutige ID ist. Würden Sie eine komplexe "Manager" -Klasse mit einfachen ExampleClasses oder eine komplexe ExampleClass mit einem einfachen Manager empfehlen? Gibt es eine allgemein akzeptierte Antwort, oder hängt es von jedem einzelnen Fall ab? – tmakino

+0

Wie ich es sehe, ja, hast du deine eigene Frage beantwortet :-) Wenn die 'ExampleClass' die alleinige Verantwortung für Statusänderungen hat, mache den Setter' private' und den Getter 'public'. Sie sollten den Setter auch als 'internal' betrachten, wenn andere Klassen _in Ihrer Assembly_ ihn ebenfalls ändern könnten. –

0

"Wie viel Management sollte meine Managerklasse machen?" Ihre Option 2 ist der "Mikromanagement" -Ansatz - dass der Manager der ExampleClass jedes kleine Detail vorschreiben sollte, was und wie es zu tun ist.

In der Regel ist das strukturbasierte Programmierung als objektorientierte Programmierung. Ich würde erwarten, dass Ihr Vorgesetzter Ihrem Objekt sagt "Mach das" und mach dir keine Sorgen um die Details. Die ExampleClass sollte das gesamte Verhalten intern verkapseln und den Manager nicht zwingen, sich darum zu kümmern.

Meine Stimme ist für die Option 1, mit dem Vorbehalt, dass diese allgemeinen Prinzipien, und Sie werden immer in der Lage sein, etwas Fall zu finden, wo Sie Option 2.

eine Frage stellen wollen - gibt es einen Grund dass ExampleClass.Enabled.get öffentlich ist, abgesehen davon, dass der Manager dies überprüft? Wenn das der einzige Grund ist, warum es öffentlich ist, dann ist es eine interne Implementierung, und der gettor sollte privat sein. Wenn Sie viele Dinge in diesem Bereich suchen, könnte dies bedeuten, dass Ihr Option 2-Workflow für diese Klasse natürlicher ist.

0

Ich würde Option 2 wählen, classManager sollte die Objekte verwalten, sollte er wissen, ob das Update feuern oder nicht. Die Update-Methode des einzelnen Objekts sollte tun, was es sagt (das Objekt aktualisieren und nichts tun).

@caerolus: Ich kann noch nichts sagen ... sowieso weder von dem gegebenen Beispiel des Gesetz des demeter brach

Auf jeden Fall denke ich, das eine etwas persönliche Wahl Frage ist, vielleicht für Stapelaustausch mehr geeignet, es ist?

0

Nehmen wir an, Sie haben zwei Objekte, Firma und Mitarbeiter. Haben Sie die Firmenkontrolle, wenn der Mitarbeiter hungrig ist, oder haben Sie die Mitarbeiterkontrolle, wenn er hungrig ist? Klingt so, als ob der Angestellte überprüfen soll, ob er hungrig ist, oder? Aber wenn das Unternehmen für alle Mitarbeiter Essen bestellen möchte, muss das Unternehmen prüfen, ob der Mitarbeiter hungrig ist.

Also mein Punkt ist, es hängt vom Design und dem Kontext ab, wann zu überprüfen ist und wer überprüft und warum. In Ihrem Beispiel würde ich sagen, dass es nicht wichtig ist, weil der Kontext nicht festgelegt ist.

+0

Schönes Beispiel! Aber ich denke, es ist eher so: Die Operation ist 'Eat' (' Update' hier). Wer entscheidet, ob man isst oder nicht? Der Arbeitnehmer. Darf das Unternehmen prüfen, ob ein Mitarbeiter "hungrig" ist ("aktiviert") oder nicht? Ja, aber letztendlich ist es die Entscheidung des Mitarbeiters zu essen oder nicht. So können Sie alle wissen lassen, ob Sie hungrig sind oder nicht, aber nur Sie sollten entscheiden, ob Sie essen oder nicht ... und deshalb nicht mehr hungrig sein. –

Verwandte Themen