2009-06-04 5 views
1

Angenommen, Sie haben eine Bibliothek, die auf zwei Ebenen entwickelt wurde: eine Core-, eine Low-Level- und eine High-Level-Bibliothek. Mein Entwurf konzentriert sich darauf, die Kopplung zwischen den beiden zu reduzieren.Encapsulate Aufzählungen oder nicht?

Eine der Routinen der Schicht auf hoher Ebene akzeptiert eine Aufzählung (z. B. FOO = 0, BAR = 1, BAZ = 2). Diese Aufzählung wird direkt von den Routinen niedriger Ebene für ihre Endzwecke verwendet.

Um dies zu entwerfen, ich habe drei Möglichkeiten:

  1. Die hohe Routine eine Aufzählung der hohen Modul verkapselt akzeptiert und übersetzt eine Eins-zu-eins den hohen Pegel Enum in den Enum Low-Level Werte. Vorteile: Untere Kupplung. Nachteile: Ich wiederhole mich selbst
  2. Die High-Level-Routine akzeptiert die Aufzählungswerte des Low-Level-Moduls, und übergeben Sie es "wie es ist". Vorteile: weniger Tipparbeit, weniger Duplizierung. Nachteile: höhere Kopplung.
  3. Ich erstelle ein "Enumerationsmodul", das extern ist und beide Ebenen von diesem Aufzählungsmodul abhängen. Vorteile: konzeptionelle Klarheit. Nachteile: Uber Catch-All-Modul mit Aufzählungen, die nicht in der Nähe ihres Codes sind.

Haben Sie irgendwelche Erfahrung in diesem Fall? Ich würde mit 1 gehen, da es die Kopplung reduziert, aber ich würde gerne Ihre Erfahrung auch hören.

Antwort

1

Klingt High-Level-Schicht wird ein Befehl oder Parameter vom Benutzer zu akzeptieren, dass es geht entlang an die Low-Level-Ebene, ohne wirklich wissen zu müssen, was sie sagt.

Wenn das der Fall ist, dann Option # 3: "break it out" ist der Weg zu gehen.

Wenn die High-Level-Ebene einige Verarbeitungen für den Befehl oder den Parameter ausführen muss, UND sie an die Low-Level-Ebene übergeben werden müssen, besteht eine gute Chance, dass Sie etwas in Ihrer Abgrenzungsdefinition verwischen die Schichten. Die Schichten sollten sich nicht um das interne Geschäft des anderen kümmern.

Wenn Sie dies tun müssen, ist das Ausbrechen noch wichtiger, da BEIDE Layer von der Aufzählung abhängig sein sollen, und Sie WÜNSCHEN eine Änderung in der Aufzählung, um (zumindest) die Neukompilierung beider Seiten zu erzwingen . (make, dependencies, etc ...)

Lesen Sie Dijkstras Klassiker "Struktur des Multiprogramming-Systems" und reflektieren Sie, was es über die Schichtphilosophie sagt. Es ist auf der Website des UT Austin CS Department im Dijkstra-Archiv.

2

Ich denke, das hängt davon ab, ob Ihre Ebenen Ebenen oder Ebenen sind.

Wenn das Low-Level-Modul hinter einer Web-Service-Schnittstelle ist, würde ich für # 1 gehen, was im Wesentlichen durch den für Sie generierten Proxy-Code erreicht wird (sicherlich im Fall von WCF oder amsx-Services).

Wenn es sich um verschiedene Assemblys handelt, die im gleichen Prozess ausgeführt werden, wäre ich eher geneigt, eine gemeinsame Codelösung zu verwenden, wahrscheinlich durch Erstellen einer separaten Assembly mit Kern-Enums und -Schnittstellen.

2

Ich habe hier nicht viel das Kupplungsproblem bekommen. IMHO, sollten beide Ebenen die gleiche Aufzählung (etwas mehr wie Option 3) sehen. Die Namen in der Enumeration sollten Namen auf hoher Ebene sein (also wer sie liest, kann sie gut verstehen, braucht die niedrige Ebene nicht zu verstehen), und ihre Werte sollten für den Teil auf hoher Ebene unwichtig sein.

Ein Problem, das ich mit Nummer eins sehe, ist ein größerer Wartungsaufwand und eine größere Anfälligkeit für Fehler. Angenommen, der Wert einer Aufzählung ändert sich, oder Sie fügen ein anderes Element hinzu. Sie müssen daran denken, es in beiden Teilen zu ändern, sonst könnten Sie unerwartetes Verhalten und inkonsistente Daten in Ihren Anwendungen haben. Außerdem werden Sie eine Übersetzungsschicht benötigen, in mehr Code resultieren zu halten

Hoffe, es hilft :)