2009-07-07 4 views
9

ein Punkt des architektonischen Stils, dass ich Ihre Meinung über bitte haben möchte:OO Coding - Object Manager verwenden oder nicht?

Mein ORM hat mir ein Benutzerobjekt gegeben, das einem Benutzer meines Systems entspricht. Ich wollte eine Reihe von Methoden für die Behandlung von Benutzern entwickeln - GetByUsername(), Authenticate(), VerifyLoginPassword() usw. Ich glaube jedoch, dass einige dieser Methoden nicht wirklich zur Benutzerklasse gehören - z. GetByUsername() fühlt sich zumindest wie eine statische Methode von User an, aber wäre es nicht "sauberer", eine andere Klasse zu haben, sagen wir "UserManager", die uns diese Art von Aufgaben zur Benutzerverwaltung zur Verfügung stellt? Es erscheint ein wenig seltsam, dass eine Benutzerinstanz die Authenticate() -Methode enthält, zum Beispiel, wenn es das Sicherheitssystem ist, das die Authentifizierung vornimmt?

Die Sache, um die ich mir Sorgen mache, ist, dass ich dieses Modell bis zu dem Punkt beende, wo die User-Klasse nicht mehr als eine Struktur ist, und meine User Manager- und Security Manager-Klassen tatsächlich alle Methoden arbeiten. Es ist nicht sehr "OO", wenn all diese Manager-Klassen leichte Objekte manipulieren.

Alle Gedanken oder Links zum Stand der Technik zu diesem philosophischen Thema wären willkommen!

Antwort

6

Es klingt wie Sie an diesem Punkt, wo Sie über die Definition Objekte bewegen als „ein Hund ist-ein Tier“ und der Umzug in Objektdefinitionen in Bezug auf Rollen, Verantwortlichkeiten und Verhaltensweisen.

ich dieses Buch empfehlen Ihnen, dass der Übergang machen zu helfen und wirklich „es bekommen“:

Object Design: Roles, Responsibilities, and Collaboration

Ich habe keine Antwort auf Ihre Frage, weil es ein so grundlegender Bedeutung ist Design-Entscheidung, dass Sie wirklich über das "größere Bild" lernen sollten. Dieses Buch gibt Ihnen eine gute Grundlage in den Prinzipien und Techniken des Responsibility-Driven Design.

Genießen,

Robert C. Cartaino

+1

Mein Gott, das ist ein teures Buch. –

0

Die Situation, die Sie beschreiben, hängt damit zusammen, ob Objekte dem Self-Servicing- oder Adapter-Muster zum Speichern in einem Repository (d. H. Datenbank) folgen.

Self-Service würde Objekte speichern "selbst" wie in myObjectInstance.Save(), während das Adapter-Muster wäre myObjectAdapter.Save(myObjectInstance).

Das Adapterformular wird häufig bevorzugt, da es die Repository-Funktionalität von Objekten entfernt.

+0

Warum nennst du es Adapter? Hat es etwas mit diesem Adaptermuster gemeinsam? http://en.wikipedia.org/wiki/Adapter_pattern –

3

Martin Fowler hat einige nützliche views on this.

Die grundlegende Wahl ist zwischen Service Locator und Dependency Injection. Der erste Punkt ist, dass beide Implementierungen die grundlegende Entkopplung bereitstellen, die im naiven Beispiel fehlt - in beiden Fällen ist der Anwendungscode unabhängig von der konkreten Implementierung der Dienstschnittstelle. Der wichtige Unterschied zwischen den beiden Mustern besteht darin, wie diese Implementierung der Anwendungsklasse bereitgestellt wird. Mit Service Locator fragt die Anwendungsklasse explizit nach einer Nachricht an den Locator. Bei der Injektion gibt es keine explizite Anfrage, der Dienst erscheint in der Anwendungsklasse - daher die Inversion der Kontrolle.

Inversion der Kontrolle ist ein gemeinsames Merkmal von Frameworks, aber es ist etwas, das seinen Preis hat. Es ist schwer zu verstehen und führt zu Problemen beim Debuggen. Im ganzen ziehe ich es vor, es zu vermeiden, wenn ich es nicht brauche. Das heißt nicht, dass es eine schlechte Sache ist, nur dass ich denke, dass es sich über die einfachere Alternative rechtfertigen muss.

1

Sie können weiterhin alle Funktionen aus Ihrer Benutzerklasse Refactoring, aber wie Sie sagten, Sie mit nichts drin gelassen kann am Ende. An diesem Punkt können Sie alle anderen Klassen, die Sie erstellt haben, bewerten und dann eine individuelle Beurteilung für jede dieser Klassen treffen, indem Sie fallweise entscheiden, ob diese Klassen genügend Funktionalität enthalten, um eine ganz neue Klasse zu rechtfertigen.

Wenn Sie entscheiden, dass einige dieser Klassen zu klein sind, können Sie ihre Funktionalität wieder in die Benutzerklasse einfügen. Ich sehe nichts falsch daran, zum Beispiel eine Validate-Funktion für den Benutzer zu haben, anstatt eine UserValidation-Klasse mit nur einer Methode zu haben.

3

Es fühlt sich nicht sehr "OO" an, dass all diese Manager-Klassen leichte Objekte manipulieren.

Ich weiß nicht, ob das sehr "OO" ist, aber für mich fühlt es sich sehr MVC und Separations-of-Concerns-Like. Sehr einfache Business-Klassen (bis zu dem Punkt, dass sie nur Datencontainer sind) und dann Repository-Objekte, die sie bewegen, sind ein übliches Muster.

1

Ich denke, Sie sind auf dem Geld, wenn Sie sagen, dass diese Methoden nicht auf dem Benutzerobjekt gehören. Die Get/Search/Save-Methoden können diskutiert werden, aber ich bin der Meinung, dass sie nicht auf dem Business-Objekt selbst sein sollten und sollten entweder mit einem Repository (das Repository-Muster) oder über Query Objects, wenn Sie nicht möchten um Ihr ORM in einem Repository zu abstrahieren.

Soweit die Authentifizierung geht, wäre es besser, eine Reihe von Klassen, die für die Authentifizierung verantwortlich sind, und lassen Sie diese aus dem Benutzerobjekt insgesamt. Diese Gruppe von Klassen könnte sich des Benutzerobjekts bewusst sein, oder besser gesagt, sie sollten sich eines Vertrags wie einer Anmeldeinformation bewusst sein.

0

Ich mag es auf eine andere Art und Weise zu setzen. Diese Methoden gehören nicht wirklich zur Domäne, da keine Geschäftslogik beteiligt ist. Ich möchte die Befehls- und Abfrage Segregation Prinzip

GetByUsername() verwenden - es ist eine Abfrage, die wirklich nicht brauchen, jede Geschäftslogik

Authentifizieren(), VerifyLoginPassword() - Diese Validierungslogik sind, die nicht angenommen wird in der Domäne durchgeführt werden. Bitte beziehen Sie sich auf dieses Dokument Set Based validation in Domain