2017-01-20 4 views
12

Beim Implementieren des Repository-Musters für mein ASP.NET-Projekt stieß ich auf einige Probleme, auf die ich mich nicht einlassen kann. Ich habe also ein paar Fragen, wie das Repository-Muster richtig implementiert werden kann.Wie man das Repository-Muster richtig implementiert?

Aus meiner Erfahrung denke ich, dass Klassen/Modelle ohne Verhalten nur in meiner Anwendung, neben ihren Repositories ist nicht gut OOP. Aber so habe ich das Repository-Muster implementiert. Ich mache einfach überall wo ich eine Repository-Instanz brauche, um einige Aktionen durchzuführen. Das Ergebnis dieses Ansatzes war, dass alle meine Domain-Klassen kein Verhalten hatten.

Sie waren nur Objekte, die Daten ohne Methoden enthielten. Mein Lehrer sagte mir, dass ich dünne Modelle benutze und dass ich mich bemühen sollte, fette Modelle zu machen. Als Reaktion auf dieses Feedback, ich implementiert einige Business-Logik in den Klassen, aber ich lief in einige Probleme:

Szenario:

Meine User Klasse eine Liste der Freunde mit Benutzerobjekte in sich hatte, zu repräsentieren die Freunde eines bestimmten Benutzers. Wenn Sie einem Benutzer einen neuen Freund hinzufügen, überprüft die Domänenklassenmethode, ob der "Freund" bereits in der Freundesliste vorhanden ist. Wenn nicht, wird er zur Liste hinzugefügt. Diese Änderungen müssen zur Persistenz an die Datenbank gesendet werden.

Ich weiß, dass dies im Repository für jede Domänenklasse getan werden muss, aber wo gehören die Aufrufe der Repository-Methoden in die Architektur der Anwendung?

Gerade jetzt nenne ich die Repository-Methoden in den Domänenklassenmethoden selbst in die Datenbank Änderungen bestehen bleiben:

public void AddFriend(User friend) 
    { 
     foreach(User f in Friends) 
     { 
      if(f.Username == friend.Username) 
      { 
       throw new Exception(String.Format("{0} is already a friend.", friend.Username)); 
      } 
     } 

     Friends.Add(friend); 
     userRepo.AddFriend(this.Id, friend.Id); 
    } 

Ist dies ein guter Ansatz, weil der aus irgendeinem Grunde denke ich, dass es nicht. Was den Komponententest anbelangt, so benötigen wir bei diesem Ansatz eine Abhängigkeitsinjektion, die mir sagt, dass es keine unabhängige Klasse (gut testbare Einheit) ist. Ich habe einige Posts von Leuten gelesen, die sagen, dass sie eine zusätzliche Service-Schicht oder etwas verwenden. Ich denke, diese Art von Abstraktion wird hier benötigt, aber wie sieht eine bestimmte Service-Ebene aus? Was ist drin, welche Methoden etc.?

Ich habe einige andere Schüler gesehen, die statische Methoden in einer Domänenklasse verwenden, die Funktionen wie das Hinzufügen eines neuen Objekts, das Aktualisieren eines Objekts, das Löschen eines Objekts und das Abrufen aller Objekte bietet.

Beispiel:

public class Tram 
{ 
    private static TramRepository Repo = new TramRepository(new DBTram()); 

    public static void AddTram(int tramID, TramType type, int lineNr) 
    { 
     Tram tram = new Tram(tramID, type, TramStatus.depot, lineNr, true, null); 
     Repo.AddTram(tram); 
    } 

    public static List<Tram> GetAll() 
    { 
     Repo.GetAll(); 
    } 
} 

ich es eine seltsame Sache, finden eine Methode, um eine neue Einheit in die Datenbank in einer Domäne Klasse hinzufügen, die das Unternehmen selbst ist. Auch für die GetAll() Methode finde ich es komisch, eine Methode in einer Klasse zu haben, die alle Straßenbahnen bekommt. So kann ein Straßenbahnobjekt alle Straßenbahnen bekommen. Ich denke, das ist eine seltsame Art, das Repository-Muster zu implementieren. Habe ich recht?

Also, welche Art von Abstraktion ist hier erforderlich? Muss es eine zusätzliche Schicht geben? Wenn ja, wie sieht diese Schicht aus? (Beispielcode) Oder suche ich in die falsche Richtung und gibt es eine andere Lösung, die das Problem des Unit-Tests mit dem Repository-Muster kontert?

Dieses Architekturproblem, auf das ich jedes Mal stoße, stellte sicher, dass ich es beantworten muss.

Ich finde es schwierig, dieses Problem klar zu erklären, aber ich hoffe, ihr versteht es.

+1

Dies ist möglicherweise eine bessere Frage zu Software Engineering anstelle von Stack Overflow, wenn Sie sich Gedanken über Methoden und ideologische Entwurfsmuster machen. – TylerH

+1

Es ist sehr merkwürdig, dass diese Frage aufgestanden * und * auf Eis gelegt wurde (die Tatsache, dass die Leute die Frage auffrischten, deutet darauf hin, dass die meisten die Frage gut/interessant halten), ich hätte nicht abgestimmt, um zu schließen. Allerdings lohnt es sich, dies auf Software Engineering zu übertragen. – EJoshuaS

+0

Ich habe die Frage bearbeitet, so dass sie weniger breit und weniger meinungsbasiert ist. Anstatt zu fragen, was ihr von Designproblemen hältst, frage ich jetzt nach einer bestimmten Lösung für mein architektonisches Problem. – Maikkeyy

Antwort

2

Ihre Fragen sind absolut normal, aber erwarten Sie keine absolute Antwort. Willkommen in der Softwarebranche!

Hier ist meine Meinung:

  1. Ist es gut OOP eine Anwendung, die auf einer Architektur beruht, die neben ihren Repositories, nur Modelle/Klassen , die ohne Verhalten halten Werte hat?

Ich glaube, Sie versuchen, ein Repository-Muster zu implementieren, aber Sie vermissen eine höhere Architektur Aussicht. Die meisten Apps sind zumindest in 3 Ebenen entkoppelt: View (Präsentation), Business und DataAccess. Die Repository-Muster finden im DataAccess statt, hier finden Sie ein reines Datenobjekt. Diese Datenzugriffsschicht wird jedoch von einer Business-Schicht verwendet, in der Sie ein Domänenmodell, Klassen mit Geschäftsverhalten UND Daten finden. Der Testaufwand der Einheit muss auf dem Domänenmodell in der Business-Schicht erfolgen. Diese Tests sollten sich nicht darum kümmern, wie die Daten gespeichert werden.

  1. Wo kann ich Repository-Methoden in der Architektur der Anwendung aufrufen?

Wieder keine absolute Antwort, aber in der Regel ist es sinnvoll etwas wie ein Business-Service zu nutzen. Diese Dienste können den Datenfluss zwischen verschiedenen Domänenobjekten organisieren und laden und in Repositories speichern. Dies ist im Grunde, was Sie in Ihrer AddFriend-Klasse tun, und es gehört in eine Business-Schicht.

In Bezug auf Unit-Tests haben wir mit diesem Ansatz müssen einige dependancy Injektion, die mir sagt, dass es

keine unabhängige Klasse

Business-Services sind ususally abhängig von Repositorys, ist es ein wirklich allgemeiner Fall für Unit-Tests. Die Tram-Klasse kann geschäftlich handeln und ist immer noch unabhängig. Der AddTram-Business-Service benötigt ein Repository und die Dependency-Injection ermöglicht es, diese trotzdem zu testen.

  1. Methoden, die, Update einfügen und neue Objekte in einer Datenbank löschen, sind sie in einer Klasse sein sollten selbst?

Für diese, die ich klar sein kann und laut: bitte das nicht tun, und ja, gehören CRUD-Operationen an der Straßenbahn Repository. Es ist sicherlich keine Geschäftslogik. Aus diesem Grund in Ihrem Beispiel benötigen Sie zwei Klassen in zwei verschiedenen Schichten:

  • Tram konnte das Business-Objekt in der Business-Schicht sein (No Crud Betrieb hier)
  • TramRepository ist das Objekt, das die Daten speichern müssen für eine Straßenbahn (wo Sie die CRUD Betrieb finden)

„Weil ich habe einige andere Studenten gesehen stellt die Verwendung von statischen Methoden machen in einer Domäne-Klasse, die diese Funktionalität“

Die Verwendung von statischen Methoden ist eindeutig keine gute Idee dafür, es bedeutet, dass jemand Daten durch Ihr Objekt speichern könnte, obwohl es sich um Business Case handelt. Und wieder ist Datenspeicherung kein Business Case, sondern eine technische Notwendigkeit.

Nun, um fair zu sein, müssen alle diese Konzepte im Kontext diskutiert werden, um Sinn zu ergeben, und müssen bei jedem neuen Projekt angepasst werden. Deshalb ist dein Job hart und aufregend: Kontext ist König.

Auch ich schrieb eine blog article zentriert auf MVVM, aber ich denke, es kann helfen, meine Antwort zu verstehen.

+0

Liebe die down-Stimmen, aber jeder Kommentar, um mir zu helfen, meine Antwort zu verbessern, wäre willkommen? Thx – Ouarzy

+1

Hallo, danke für deine Antwort. Ich habe deine Antwort nicht abgelehnt, da ich gerade im Moment arbeite, also werde ich es ausgiebig lesen, wenn ich zu Hause bin. Aber über die Service-Schicht, auf die Sie sich beziehen, haben Sie ein Beispiel dafür, wie es aussieht? Weil ich sie noch nie zuvor gesehen habe. – Maikkeyy

+0

Ich habe Ihre Antwort aktualisiert. Ich habe diese Art von Design/Architektur für eine Unternehmenslösung erlebt. Drei Schichten mit Datenschicht unten, unterstützt von der Business-Schicht über der Datenschicht. Aber modetn Web-Entwickler und Frameworks wie ROR, LARAVEL betonen solche Muster kaum. MVC für Web Services hat die Dinge stark eingeschränkt, wo Verhalten oder Domain auf den Controller verschoben wurden. Sie können auch am Modell selbst eingekapselt werden. – user3775217

0

Das Ergebnis dieses Ansatzes war, dass alle meine Domain-Klassen buchstäblich kein Verhalten hatten. Sie waren nur Objekte, die Daten ohne Methoden enthielten.

  1. Ist es gut OOP eine Anwendung, die auf einer Architektur beruht, die neben ihren Repositories, nur Modelle/Klassen hat, die Werte ohne Verhalten halten?

Nein natürlich nicht, aber das ist, wie Web-Entwickler in diesen Tagen unterrichtet werden.

Es ist wieder der alte modulare Programmierstil aus den 1970er Jahren (statische Klassen + Daten in Objekten).
Modulares Programmieren verursachte viele Probleme, deshalb erfanden sie Kapselung und objektorientierte Sprachen, um sie zu lösen.

machen alle Daten öffentlich so lange in Ordnung sein wird, wie Sie einfache Webseiten machen:

  • Belastungsdaten
  • Anzeigedaten
  • Daten speichern

Die Probleme beginnen, wenn Sie brauchen komplexes Verhalten - dann sind Ihre Daten tatsächlich Teil der Implementierung der Software und Sie haben sie veröffentlicht! Dies führt zu schwerwiegenden Wartungsproblemen, wenn mehrere Entwickler an demselben Projekt arbeiten.

Webentwicklern wird OOP nicht beigebracht. Ihnen wird eine einfache Art der Programmierung beigebracht - sie werden auf einfache Webseiten gelenkt (was die Regierungen brauchen).

+1

Ich stimme mit "Web-Entwickler werden nicht unterrichtet, oops". Eigentlich sind Webentwickler selbst nicht daran interessiert, Oops zu lernen oder sind ihnen ausgesetzt.Mit dem Aufkommen von MVC-Frameworks wie ROR, LARAVEL oder etc, neigen Webentwickler dazu, Domain/Verhalten in Controllern an die Spitze zu bringen. Ich habe selbst viele Entwickler gesehen, die dieser Praxis folgen. Die Notwendigkeit, die Domäne oder das Verhalten in einer Ebene unterhalb von Controllern einzukapseln, drängt moderne Entwickler nicht. – user3775217

Verwandte Themen