Laden...

Fragen zur Projektstruktur

Erstellt von ilcsh vor 10 Jahren Letzter Beitrag vor 10 Jahren 3.542 Views
I
ilcsh Themenstarter:in
25 Beiträge seit 2013
vor 10 Jahren
Fragen zur Projektstruktur

Hallo,
ich muss eine neue Anwendung erstellen und da stellt sich mir die Frage, wie die Projekt (Solution) Struktur ausschauen soll. Da ich in noch nie mit Unity bzw. mit Schnittstellen gearbeitet habe, habe ich ein paar Fragen.
Kurz zur Anwendung, diese um es einfach auszudrücken, verwaltet Listen. Es gibt

  • Login
  • Main -> Übersicht der Listen mit Filter Funktion
  • Neue Liste anlegen (Beschreibung, Datum sowie Kategorie)
  • Passwort/Namen ändern
  • Export (PDF)
  • und noch einige kleine Funktionen

In der Datenbank wird nur mit Stored-Procedures gearbeitet. Zum Loggen verwende ich NLog und die Datenbank soll MySQL oder PostgreSQL sein.
Ich möchte das Microsoft Unity benutzen um evtl. Später die Datenbank oder den Logger tauschen zu können. Ich habe mir das Buch sowie nen Webcast zu diesen Thema angeschaut (Unity: Einführung in Dependency Injection und Foundations of Programming Ebook)

Zu meinen Fragen nochmal:

  • Wie könnte hier die Projekt (Solution) Struktur ausschauen (Welche Projektmappen gibt es? Bild)
  • Ist hier ein 3-Schicht-Modell gut (HowTo: 3-Tier / 3-Schichten Architektur)
  • SOLID design principles?
  • Domain Driven Design pattern?

Vielen Dank vorab und Grüße

5.742 Beiträge seit 2007
vor 10 Jahren

Hallo ilcsh,

ohne deine Frage im Detail zu beantworten, ein paar Anmerkungen meinerseits:

Beide der Links sind von 2008. Das heißt jetzt prinzipiell erst einmal nichts, aber wenn du ein neues Projekt beginnst, solltest du dir bewusst sein, dass die Links aller Voraussicht nach nicht den aktuellen Stand der Technik widerspiegeln könnten.

3-Schichten Modelle sind grundsätzlich sinnvoll, allerdings würde ich bei einem neuen Projekt zu einem sogenannten ORM (Object-Relational-Mapper) raten. Hier sind vor allem NHibernate und LinqToEntities (Entity Framework, EF) verbreitet.
Beide bieten auch Support für LINQ-Expressions, sodass du zum DB-Zugriff z.B. Code schreiben kannst wie:


Customer customer = context.Customers.Where(c => c.LastName == "Müller").FirstOrDefault();

IMHO erleichtert das die Arbeit mit einer DB erheblich, indem es die Menge an (Infrastruktur-)Code deutlich reduziert.

Zum anderen solltest du unbedingt auch ein Design-Pattern für dein UI verwenden: Unter WPF wäre das meiner Meinung nach am besten MVVM und unter WinForms MVP (in der Ausprägung Passive View - wobei es hier verschiedene Standpunkte gibt).

Die Entscheidung für einen DI-Container ist sehr löblich, evtl. kannst du auch mal einen Blick auf andere Container werfen. Ist nur eine persönliche Ansicht, aber IMHO ist Unity nicht der beste, den es gibt.

Bzgl. Projektstruktur würde ich mir zu Beginn noch keine allzu großen Sorgen machen - das ist etwas, was man später auch noch leicht ändern kann.
Beginnen kannst du z.B. mit vier Projekten:

  • Views (enthält alle Controls + Codebehinds)
  • Presenters (alle Presenter aus MVP)
  • Models (alle Businessobjekte + Klassen für NHibernate)
  • App (verbindet alles)
I
ilcsh Themenstarter:in
25 Beiträge seit 2013
vor 10 Jahren

Hey winSharp93,

danke für deine Antwort.
Ich wollte mit WinForms arbeiten da ich mich mit WPF nicht auskenne.
Wo würden dann die Interfaces reinkommen?
Mit NHibernate und LinqToEntities habe ich noch nie gearbeitet, kannst du mir gute Tutorials auf deutsch empfehlen? Bisher habe ich eine Datenbank Klasse die, die Verbindung zu DB herstellt sowie z.B. DataTable's zurückgibt oder Befehle ausführt, so habe ich es bisher gemacht.

Grüße

5.742 Beiträge seit 2007
vor 10 Jahren

Wo würden dann die Interfaces reinkommen?

Kommt darauf an, welche 😉
Generell ist die Aufteilung auf mehrere Projekte vor allem sinnvoll, wenn sich nicht alle gegenseitig referenzieren. Folglich sollten die Interfaces in das Projekt, wo sie Sinn machen - eine Auslagerung in ein separates Projekt würde ich erst durchführen, wenn das tatsächlich benötigt wird (z.B. wenn das DB-System ohne Rekompilierung ausgetauscht werden soll).

Bisher habe ich eine Datenbank Klasse die, die Verbindung zu DB herstellt sowie z.B. DataTable's zurückgibt oder Befehle ausführt, so habe ich es bisher gemacht.

Davon würde ich mich eher verabschieden: DataSets sind zwar in manchen Situationen ganz nett, taugen aber IMHO nicht als Ersatz für Businessobjekte (eingeschränkte Validierungsmöglichkeiten, kein Einbau von Funktionalität möglich, ...).

Mit NHibernate und LinqToEntities habe ich noch nie gearbeitet, kannst du mir gute Tutorials auf deutsch empfehlen

Auf deutsch ist immer so eine Sache... Weitaus mehr findet man auf Englisch.
Spontan bin ich z.B. auf: Zweiter Start mit NHibernate gestoßen - allerdings ist das doch recht oberflächlich.

2.298 Beiträge seit 2010
vor 10 Jahren

Davon würde ich mich eher verabschieden: DataSets sind zwar in manchen Situationen ganz nett, taugen aber IMHO nicht als Ersatz für Businessobjekte (eingeschränkte Validierungsmöglichkeiten, kein Einbau von Funktionalität möglich, ...).

Wir handhaben das im Unternehmen so, dass wir ebenfalls eine Schnittstelle verwenden, welche DataSets etc. zurück liefert.

Anschließend führen wir das Mapping auf die Objekte im Code durch. - Ist nicht unbedingt der beste Weg. Aber es funktioniert und ist einfach zu verwenden. Da gibt es zwar noch eine Hintergrundgeschichte zu, aber die ist nicht von relevanz.

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

I
ilcsh Themenstarter:in
25 Beiträge seit 2013
vor 10 Jahren

Puh, das wird nicht ganz leicht 😃
Ich werde mal versuchen wie weit ich komme 😃

Danke aber euch beiden schonmal ;I

2.207 Beiträge seit 2011
vor 10 Jahren

Hallo ilcsh,

wow, du fragst hier Sachen, die Bücher füllen 😉

Grundsätzlich: Verabschiede dich von dem Gedanken, dass du zum Projektanfang eine Struktur festlegst und diese bis zum Ende so bestehen bleibt. Das ist in 99,999% der Fälle nicht möglich. Es kommt immer was dazu, etwas weg, etwas hin oder her und am Ende sieht es anders aus als geplant. Das ist nichts schlechtes, im Gegenteil: Das kann sogar sehr gut sein!

Benutze für das Datenbank-Zeug OR-Mapper oder ähnliches. Wie WinSharp schon sagte. Halte es zumindest seperat.

Bisher habe ich eine Datenbank Klasse die, die Verbindung zu DB herstellt sowie z.B. DataTable's zurückgibt oder Befehle ausführt, so habe ich es bisher gemacht.

Das verstösst konkret gegen das Single-Responsibility-Prinzip. Eine Klasse sollte demnach die Verbindung mit der Datenbank herstellen (etc.) und eine sollte lesen und die Datasets zurückgeben. (Repository, Provider, etc.) Du solltest dir vielliecht mal Patterns allgemein ansehen.

Auch eine n-Schichten-Architektur ist nichts schlechtes, also fährst du sicher mal gut damit. Ob du nun die Klassen flach in das Projekt legst oder in Namespaces machst, eventuell sogar noch die Implementationen in eigene Namespaces legst und die Interfaces heraus: Das musst du wissen. Stichwort "Clean-Code".

Wenn du eine Schicht dem kompletten Projekt anbietest und nicht willst, dass die Schicht darüber etwas von der Implementation der Schicht darunter weiss, kannst du auch ein eigenes Interface-Projekt machen. Dann wird nur das referenziert. Das Impl-Projekt implementiert dann die Interfaces aus.

Login: Könnte ein Service machen, braucht aber auch UI. VM könnte den Service injected bekommen.
Main: UI: Zeigt Listen an, Service ins VM injecten, der dir die Listen anbietet, dann auf dem VM anbieten und im UI anzeigen
Export / PDF: Könnte ein PDF-Service machen. Braucht kein UI, solltest du aber getrennt halten (Interface, Implementation)
und und und...

Das sind nur Vorschläge, wie man es machen könnte, es gibt etliche Möglichkeiten

Fazit: Es gibt viele viele Möglichkeiten dahin zu kommen, wo du hinmagst. Welche letztendlich die Beste für dich ist, musst du wissen. Clean-Code, Single-Responsibility, Repository-Pattern, MVVM, und und und sind sicherlich Hilfen.

Setz dich damit mal auseinander

Gruss

Coffeebean

PS:

Ich wollte mit WinForms arbeiten da ich mich mit WPF nicht auskenne.

MVVM hat eine recht "saubere" Architektur was den UI Part angeht. Und schwer ist es auch nicht. Schau es dir mal an 😉

I
ilcsh Themenstarter:in
25 Beiträge seit 2013
vor 10 Jahren

Hey Coffeebean,

danke für deine Antwort.
Ich habe laange so Programmiert (Arbeit, mehr möchte ich hier nicht eingehen, ich möchte mich selber weiterbilden da ich dort keine Unterstützung erhalte (in Form von Bücher, Zeit etc.)):

  • Projektname.Klassenbibliothek (clsProjektname)
  • Projektname.App (WinForms)

Ich habe mir das NHibernate mal angeschaut.
Habe ich das richtig verstanden, meine Tabellen sowie derren Spaltennamen, erstelle ich in Klassen? Ist das auch empfehlenswert wenn ich SQLite verwenden möchte?
Was ich noch nicht verstehe, ich hatte Stored Procedures, kann ich die hier vergessen?
Wie schaut es aus wenn ich abfragen wie Inner Join habe?

Ich habe mir das jetzt anfangs so vorgestellt:

Projekt -> Hier ist die UI (WPF oder WinForms)
Projekt.Service -> Die ganzen Interface
Projekt.Domain -> Da sind die Klassen der DB (NHibernate )
Projekt.Repository -> Hier werden die Klassen erstellt (durch die Interfaces)

5.742 Beiträge seit 2007
vor 10 Jahren

Habe ich das richtig verstanden, meine Tabellen sowie derren Spaltennamen, erstelle ich in Klassen? Ist das auch empfehlenswert wenn ich SQLite verwenden möchte?
Was ich noch nicht verstehe, ich hatte Stored Procedures, kann ich die hier vergessen?
Wie schaut es aus wenn ich abfragen wie Inner Join habe?

Grundsätlich funktioniert NHibernate mit so ziemlich allen DB-Systemen, mit recht großer Sicherheit auch mit SQLite. Du kannst das DBMS dann auch später recht einfach austauschen.

Im Prinzip trifft es dann schon: Je Tabelle eine Klasse, je Spalte ein Feld. Gibt aber auch komplexere Mappings für Vererbung etc. Wenn du eine genauere Frage hadt, am besten in Datentechnologien stellen.
Für den Anfang bietet sich evtl. ein kleines Testprojekt an, in dem du etwas den Umgang mit Nhibernate übst.

Stored Procedures kannst du zwar einbinden, ich würde aber im Normalfall nicht dazu raten, diese allzu exzessiv einzusetzen. Führt meist zu versteuter Anwendungslogik, schlecht gemanagetem SQL-Code (Versionsverwaktung usw. wird da gerne mal eingespart) und anderen Problemen.

Ich habe mir das jetzt anfangs so vorgestellt:

Was sollen wir groß sagen?
Klar - ist eine Möglichkeit. Wie gesagt: Die "richtige" Lösung gibt es nie.
Die Namensgebung des Repository Projektes ist aber IMHO etwas verwirrend, da ein Repository im Normalfall eine Klasse für den DB-Zugriff darstellt.

I
ilcsh Themenstarter:in
25 Beiträge seit 2013
vor 10 Jahren

Klar - ist eine Möglichkeit. Wie gesagt: Die "richtige" Lösung gibt es nie.
Die Namensgebung des Repository Projektes ist aber IMHO etwas verwirrend, da ein Repository im Normalfall eine Klasse für den DB-Zugriff darstellt.

Upps, ok. Danke.
Wenn ich das jetzt so in etwa aufteile, habe ich schonmal ne grobe Struktur 😃

Hinweis von herbivore vor 10 Jahren

Und damit sollte das Ziel des Threads erfüllt sein, bevor das hier ein Sammel-Thread zu allen Fragen um Software-Architektur wird, siehe [Hinweis] Wie poste ich richtig? Punkt 1.2. Ansonsten ist das - wie Coffeebean schon andeutete - ein Fall für ein oder mehrere Bücher.