Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Die ideale Architektur für Businessapplikationen?
Golo Roden
myCSharp.de - Member

Avatar #avatar-2167.png


Dabei seit:
Beiträge: 4649
Herkunft: Riegel am Kaiserstuhl

Themenstarter:

Die ideale Architektur für Businessapplikationen?

beantworten | zitieren | melden

Hallo,

obwohl es ja einige Ansätze gibt, wie man Businessanwendungen aufbauen sollte (3-Tier, MVC, ...), ist es in der Praxis ja doch immer noch eine andere Sache, eine wirklich skalierbare, durchdachte Architektur aufzusetzen.

Deshalb würde ich hier gerne mal diskutieren, wie man so etwas idealerweise aufbauen würde. Mir ist klar, dass es nicht DIE ideale Architektur gibt, aber ich denke, es lassen sich doch etliche Best Practices finden, die man verwenden kann.

Um mal den Anfang ganz unten zu machen: In der Regel hat man ganz unten ja so etwas wie eine Datenzugriffsschicht, sei es auf eine Datenbank, einen Webservice, eine XML-Datei oder sonstwas ... in der Regel wird hier mit Entities gearbeitet, wobei üblicherweise ein Entitiy einem Datensatz einer Tabelle entspricht. Im Prinzip sollte man jedoch hier bereits mehrere Schichten einziehen, nämlich:

Nach oben: Ein einheitliches Interface, das NUR mit Entities arbeitet, und abstrahiert, aus welcher Datenquelle die Entities kommen.
Nach unten: Je nach Datenquelle einen Provider, der halt auf XML, SQL oder sonstwas zugreift, und ein Entitiy zurückliefert.
Dazwischen: Einen Microkernel, um der oberen Schicht verschiedene Provider unterschieben zu können, ohne dass sie davon etwas mitbekommt.

Bereits hier sollte mit Transaktionen gearbeitet werden, zudem bietet sich in der unteren Schicht evtl der Einsatz eines O/R-Mappers an. Auch Locking sollte hier in den grundlegenden Funktionen verfügbar sein, sprich Datensatz sperren, Datensatz entsperren, usw ...

Die Entities sind zunächst auch noch sehr eng am DB-Modell, und daher nicht applikationsbezogen modelliert.

Eine Schicht darüber werden die Entities zu Businessobjekten zusammengesetzt, die dann konkret und applikationsbezogen sind. Beispielsweise könnten hier aus einem Rechnungs-Entitiy und mehreren Rechnungspositionen-Entities ein Rechnungs-BO gemacht werden, das eher aus der OOP-Sicht als aus der DB-Sicht auf eine Rechnung schaut.

Das bietet den Vorteil, dass die Entities sich ändern können, ohne dass sich die Applikationen notgedrungen mit ändern müssen. BOs sind dennoch reine Datencontainer, damit sie problemlos serialisierbar und versionierbar sind, Funktionalität würde ich hiervon in einen BO-Service entkoppeln, der nur die Workflows zur Verfügung stellt.

Das heißt auch, dass sich die Workflows ändern können, ohne dass man jedes Mal an die BOs dran muss.

Darüber liegt schließlich eine Applikations-Service-Schicht, die quasi die Applikation ohne UI darstellt, und erst darauf setzt die UI auf (im Endeffekt meine ich hier das MVVM-Pattern).

Parallel dazu gibt es einige funktionale, applikationsübergreifende Kerne, die allgemeine Sachen wie zB Drucken, Reporting, ... zur Verfügung stellen.

Und nun zu meinen Fragen:

- Was haltet Ihr von dieser Aufteilung?
- Wo würdet Ihr RPC-Grenzen ziehen? Wo würdet Ihr Stack-Grenzen ziehen?
- Wie würdet Ihr die Kommunikation über RPC aufbauen, insbesondere Events, die Rückmeldungen liefern?
- Was fehlt bei dem ganzen Ansatz?
- Wo habe ich etwas grundlegendes vergessen?

Wichtige Aspekte bei der ganzen Geschichte wären mir Multiuser, Multithreading, Skalierbarkeit, Verwendbarkeit des ganzen Grundgerüsts im Web und auf dem Desktop, und generell Flexibilität.

Viele Grüße,


Golo
Wissensvermittler und Technologieberater
für .NET, Codequalität und agile Methoden

www.goloroden.de
www.des-eisbaeren-blog.de
private Nachricht | Beiträge des Benutzers
norman_timo
myCSharp.de - Member

Avatar #avatar-1775.jpeg


Dabei seit:
Beiträge: 4591
Herkunft: Wald-Michelbach (Odw)

beantworten | zitieren | melden

Hallo Golo,

wenn man das immer nur so pauschal sagen könnte ;-))

Also ich habe schon einige Ansätze gesehen und auch diverse Richtungen verfolgt. Von einer Mini-Applikation, die quasi nur eine 2-Schichtenarchitektur beinhaltet hatte (Programm inkl. GUI plus DB) bis hin zu einer Serverlandschaft und extrem verteilte Anwendung. Dort war das GUI so weit weg, dass Daten über einen extra Provider zum Rechenzentrum geschickt wurden, diese dann zunächst vereinheitlicht und danach verarbeitet wurden, um dann wieder weiter weg über einen Provider zu so genannten Umsystemen zu schicken.

Das wohl krasseste Szenario das ich kenne ist wohl folgender Aufbau (im groben könnte man das mit einem SOA Ansatz vergleichen):

- GUI: .NET Anwendung, Daten via XML in Journalen zu
- Datenprovider: Ein spezialisierter Provider, der es schafft riesige Datenmengen über eine riesige Bandbreite zu diversesten Empfänger zu verteilen (sozusagen ein Router)
- Middleware/Businesslogik: Verarbeiter und Analysierer der Daten, hier eingesetzt BizTalk und MS-SQl Server Cluster über
- Datendateien zu Umsystemen

Grundsätzlich geht es doch immer darum: Was ist der Zweck der Software, was für Mittel stehen zur Verfügung und was ist am Effizientesten. Ich würde das wohl damit vergleichen, was für ein Warenwirtschaftssystem soll in einem Unternehmen eingeführt werden. Ein SAP System für einen Einzelunternehmen ist wohl Quatsch, genauso wie Excel für ein 10.000 Mann Unternehmen wohl nicht ausreichend sein wird.

Also da es hier sehr starke Schwankungen der Anforderungen gibt, gerade was Businessapplikationen angeht, kann man das überhaupt nicht festlegen. Wichtig für einen Software-Entwickler finde ich, ist es so viele verschiedene Ansätze zu kennen, und nicht so verbohrt zu sein, immer das Gleiche in jedem Umfeld einsetzen zu wollen.

Grüße
Norman-Timo
A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”
private Nachricht | Beiträge des Benutzers
GMLOD
myCSharp.de - Member

Avatar #avatar-2654.jpg


Dabei seit:
Beiträge: 1228

beantworten | zitieren | melden

Warum nur muss ich bei deinem Ansatz die ganze Zeit an Enterprise Java denken?
Shift to the left, shift to the right!
Pop up, push down, byte, byte, byte!

YARRRRRR!
private Nachricht | Beiträge des Benutzers
JuyJuka
myCSharp.de - Experte

Avatar #avatar-2316.jpg


Dabei seit:
Beiträge: 2282
Herkunft: Deutschland

beantworten | zitieren | melden

Hallo @All,

Eine gute Grundstruktur zu haben finde ich nicht verkehrt.
Aber mann muss eben alles Anpassen können und flexiebel sein.

Meine Strucktur besteht aus:
- O/R Mapper (als Generische DAL, mit austauschbarer Datenquelle)
- Business-Objekte
- UI

Wobei die Business-Objekte im zweifelsfall aus weiteren Schichten bestehen können und ich noch an einer Remoting-Schicht für den O/R Mapper arbeite.

Gruß
Juy Juka
private Nachricht | Beiträge des Benutzers
svenson
myCSharp.de - Member



Dabei seit:
Beiträge: 8775
Herkunft: Berlin

beantworten | zitieren | melden

Grunsätzlich glaube ich, dass Architektur weniger von Patterns, sondern eher von der Vermeidung von Anti-Patterns getrieben ist. Für Business-Anwendungen mag das weniger gelten, weil "Businessanwendung" einfach einen bestimmten Typ von Anwendung definiert, der durch Nutzerfrontend, zentraler Datenverarbeitung und -haltung definiert ist. In diesem engen Rahmen lassen sich gut Patterns definieren.

Aber die sehen bei Services schon anders aus, ebenso wie z.B. bei Steuerungen.
Dieser Beitrag wurde 3 mal editiert, zum letzten Mal von svenson am .
private Nachricht | Beiträge des Benutzers
JuyJuka
myCSharp.de - Experte

Avatar #avatar-2316.jpg


Dabei seit:
Beiträge: 2282
Herkunft: Deutschland

beantworten | zitieren | melden

Hallo svenson,

Dass Software-Architektur nicht von Patterns getrieben wird, ist hoffentlich nicht korrekt und wenn doch sehr schade. Ich glaube es nicht (dass es nicht durch Patterns getrieben wird), hab aber weder Beweise dafür noch dagegen.

Aber für die Software-Architektur gibt es ein zusätzliches Set von Patterns (oder sogar mehrer), die jedoch noch unbekannter sind als die Designe-Patterns.
z.B.: Layer-Architektur-Pattern, Pipes-and-Filter-Architektur-Pattern, Broker-Architektur-Pattern.

Gruß
Juy Juka
private Nachricht | Beiträge des Benutzers
svenson
myCSharp.de - Member



Dabei seit:
Beiträge: 8775
Herkunft: Berlin

beantworten | zitieren | melden

Was ich sagen wollte: Pattern sind Muster. Muster eigenen sich für Software von der Stange, für die Wiederholung. Stell dir vor, du musst auf einmal eine Anwendung bauen, die eine Million Transaktionen pro Sekunde verarbeiten muss. Dann kann du dein klassisches Schichten-Modell sofort in die Tonne treten und du fängst an, zuerst zu denken: Was geht auf keinen Fall: Datenbanken für Transaktionssicherung, klassische Middleware, etc.. Dann beginnt die Suche nach den Fallstricken, den No-Gos. Deine Architektur beginnt sich nicht an erfolgreichen Modellen auszurichten, sondern an den Mißerfolgen, die du gesammelt hast. Auf einmal suchst du danach, welche Muster du unbedingt vermeiden musst. Du musst deine Erfahrung in inverser Weise ins Spiel bringen.

Ansonsten lautet die Antwort auf die Frage, welche Architektur in bekanntem Umfeld die beste ist: Die alte und die bekannte. Die die andere schon 100 mal beschritten haben. Hier lauert keine Gefahr. Oder anders: Die Frage ist unspannend.

M.E. sind Musterarchitekturen - bzw. das was man als solche bezeichnet - nur Zeiterscheinungen, die den Stand der Technik bzw. der Anwendungen wiederspiegeln. "Ideal" ist ein Wort für ein Snapshot. Gestern war es das 3-Schicht-Modell, morgen die Zelle, übermorgen der Service-Ansatz. Das Pattern "Krawatte bis zum Gürtel" mag heute gültig sein. Morgen vielleicht nicht mehr. Aber das Pattern "Eine Krawatte über die man stolpert ist Scheisse" hat universelle Gültigkeit.
private Nachricht | Beiträge des Benutzers
Rainbird
myCSharp.de - Experte

Avatar #avatar-2834.jpg


Dabei seit:
Beiträge: 3953
Herkunft: Mauer

beantworten | zitieren | melden

Hallo Golo,

eine interessante Diskussion.
Zitat von Golo Roden
Im Prinzip sollte man jedoch hier bereits mehrere Schichten einziehen, nämlich:

Nach oben: Ein einheitliches Interface, das NUR mit Entities arbeitet, und abstrahiert, aus welcher Datenquelle die Entities kommen.
Nach unten: Je nach Datenquelle einen Provider, der halt auf XML, SQL oder sonstwas zugreift, und ein Entitiy zurückliefert.
Dazwischen: Einen Microkernel, um der oberen Schicht verschiedene Provider unterschieben zu können, ohne dass sie davon etwas mitbekommt.
Es gibt doch mittlerweile für jeden die passende Datenzugriffstechnologie. Das .NET Framework 3.5 SP1 liefert bereits drei Stück:
  • ADO.NET (Der schnelle Klassiker)
  • LINQ2SQL (Der schlanke OR-Mapper für treue MSSQL-Entwickler)
  • ADO.NET Entity Framework (Der Mega-OR-Mapper mit vielen Stellschrauben, eigenem DB unabhängigen SQL-Dialekt und noch LINQ obendrauf)

Deiner obigen Aussage entsprechend, ist das ADO.NET Entity Framework genau das was Du suchst: Komfortabler und Tool gestützter OR-Mapper mit völliger Abstraktion von der eigentlichen Datenquelle und auch deren API bzw. SQL-Dialekt. Volle Flexibilität, da Abfragen via LINQ (stark typisiert) oder via ESQL abgesetzt werden können. Aber da erzähle ich Dir bestimmt nichts Neues.

Ich wollte eigentlich damit sagen, dass ich das Thema Datenzugriff nicht zu hoch bewerten würde. Datenzugriff ist immer wieder das Lieblingsthema der Entwickler. Statt über Sinn und Unsinn von Mapping-Konzepten zu philosophieren, wäre es Sinnvoller, der eigentlichen Geschäftslogik einen viel größeren Stellenwert beim Entwurf einer Software-Architektur einzuräumen.
Zitat von Golo Roden
Bereits hier sollte mit Transaktionen gearbeitet werden, zudem bietet sich in der unteren Schicht evtl der Einsatz eines O/R-Mappers an. Auch Locking sollte hier in den grundlegenden Funktionen verfügbar sein, sprich Datensatz sperren, Datensatz entsperren, usw ...
Transaktionen müssen ja erst aufgespannt werden. Verschiedene Komponenten können an einer Transaktion beteiligt sein. Die Datenzugriffsschicht kann das nicht leisten, da es vom Geschäftsprozess abhängig ist, welche Operationen zusammen in einer Transaktion ausgeführt werden müssen. Deshalb haben Transaktion in der Datenzugriffsschicht eigentlich nix verloren. Aber auch das ist bereits mit System.Transactions gelöst. ADO.NET, LINQ2SQL und Entity Framework unterstützen System.Transactions-Transaktionen.
Da bleibt dann eigentlich nur die Frage, wie man seine Transaktionsklammern setzt. Etweder deklarativ im Code mit TransactionScope oder, im Falle einer verteilten Anwendung auf WCF-Basis, mit TransactionFlow-Attributen.

Du hattest noch Locking erwähnt. Beim Locking ist es selbst innerhalb einer abgeschlossenen Business Anwendung schwer, eine einheitliche Implementierung zu finden. Es gibt verschiedene Ressourcen, die unterschiedlich oft (5 pro Trag oder 200 pro Sekunde) und unterschiedlich lange (10 Sekunden oder 2 Stunden) gesperrt werden müssen. Auch der Zeitpunkt der Sperrung ist selten bei allen Ressourcen gleich. Manche müssen beim Anzeigen und andere vielleicht erst bei Beginn einer Änderung gesperrt werden. Ich würde das Locking deshalb nicht automatisch durchführen lassen, da man sonst die geforderte Flexibilität nie erreichen kann. Wenn die Infrastruktur automatisch sperrt, tut sie das immer auf die selbe Weise. In verteilten Anwendungen wird das noch wesentlich komplexer, da Clients Sperren anfordern (Im Falle eines Windows.Forms-Cients weiss z.B. auch nur diese, wann der Benutzer den Knopf "Bearbeiten" auf der Symbolleiste anklickt), aber auch serverseitige Geschäftslogik, die automatische Änderungen durchführt. Stapelverarbeitung sollte man beim Locking-Konzept auch nicht vergessen. Wie soll sich das System verhlaten, wenn z.B. ein Server-Job 1000 Buchungen ausführen soll, von denen zwei gerade durch Sperren von Clients betroffen sind, die abhängige Ressourcen gerade in Ihrer GUI bearbeiten? Letzten Stand nehmen, Erneut versuchen, Überspringen?
Ich habe gute Erfahrungen damit gemacht, einen Satz von Locking-Funktionen über eine Locking-Komponente zur Verfügung zu stellen und dem Entwickler die Verantwortung für setzen, prüfen, behandeln und freigeben von Sperren zu übertragen. Wenn eine schlanke Locking-Komponente/Dienst (Ich weiss nie, wie ich da sagen soll) zur Verfügung steht, die über ein API einfach verwendet werden kann, tut sich keiner im Team schwer mit dem Locking.
Zitat von Golo Roden
Eine Schicht darüber werden die Entities zu Businessobjekten zusammengesetzt, die dann konkret und applikationsbezogen sind. Beispielsweise könnten hier aus einem Rechnungs-Entitiy und mehreren Rechnungspositionen-Entities ein Rechnungs-BO gemacht werden, das eher aus der OOP-Sicht als aus der DB-Sicht auf eine Rechnung schaut.
Das bietet den Vorteil, dass die Entities sich ändern können, ohne dass sich die Applikationen notgedrungen mit ändern müssen. BOs sind dennoch reine Datencontainer, damit sie problemlos serialisierbar und versionierbar sind, Funktionalität würde ich hiervon in einen BO-Service entkoppeln, der nur die Workflows zur Verfügung stellt.
Meistens ergeben sich eigene Datenstrukturen zur Bearbeitung und Anzeige von ganzen Datensätzen (Weitestgehed DB-Struktur=BO-Struktur) und welche die bestimmte Sichten auf Teilaspekte einer Entität oder mehrerer Entitäten in Abhängigkeit voneinander (z.B. Trefferlisten von Suchanfragen oder Datensammlungen für Berichte).
Zitat von Golo Roden
Das heißt auch, dass sich die Workflows ändern können, ohne dass man jedes Mal an die BOs dran muss.
Das ist auch meine Meinung.
Zitat von Golo Roden
Darüber liegt schließlich eine Applikations-Service-Schicht, die quasi die Applikation ohne UI darstellt, und erst darauf setzt die UI auf ...
Diese Schicht ist der eigentliche Kern jeder Business-Anwendung. Dort spielt die Musik. Dort werden Transaktionen aufgespannt, Daten validiert, die eigentlichen Berechnungen gemacht, usw.. Trotzdem taucht diese Schicht in Architekturkonzepten oft eher als Black Box auf. Das ist dann Komponente xy, die macht das. Trotzdem geben sich viele lieber der Jagt nach dem heiligen Gral des Datenzugriffs hin, statt ihre Geschäftslogik sauber in Komponenten zu packen und deren Abhängigkeiten klar festzulegen. Das ist zugegeben auch nicht ganz einfach, da sich Geschäftslogik gerne in kleine Ritzen verdrückt. Ein bisschen wandert in SQL-Code, ein ordentlicher Happen versteckt sich in der Benutzeroberfläche und manches bleibt unauffällig in JavaScripts kleben. Deshalb sollte bei jedem Programmteil sorgfälig überlegt werden, welchee Teile der Geschäftslogik bewusst im GUI-Code, was im Code der Geschäftslogik-Komponenten/Diensten und was in der Datenbank implementiert wird.
Zitat von Golo Roden
- Was haltet Ihr von dieser Aufteilung?
Ich habe ja schon einiges direkt kommentiert. Du beschreibst eigentlich eine klassische 3-Tier Architektur. Damit habe ich gute Erfahrungen gemacht.
Zitat von Golo Roden
- Wo würdet Ihr RPC-Grenzen ziehen? Wo würdet Ihr Stack-Grenzen ziehen?
Ich würde die Anwendung in einzelne Komponenten/Dienste aufteilen, die möglichst unabhängig voneinander sind. Abhängigkeiten lassen sich natürlich nie vermeiden. Deshalb müssen sie klar geregelt werden. Mein Ansatz ist dabei, die Komponenten/Dienste in Kategorieen (nicht mit den Schichten verwechseln) einzuteilen. Diese Kategorieen könnten für eine ERP-Anwendung z.B. so aussehen:
  • Infrastruktur-Dienste (Authentifizierung, Authorisierung, Sitzungsverwaltung, Server-Jobs, ...)
  • Basis-Dienste (Mandanten-Verwaltung, Verwaltung von Grunddaten wie Einheiten, Währungen, Zahlungsbedingungen, Textbausteinen ...)
  • Stammdaten-Dienste (Artikelstamm, Geschäftspartner, Preise, Lagerverwaltung)
  • Prozess-Dienste (Angebotswesen, Einkauf, Verkauf)
  • Kontroll-Dienste (Disposition, Auswertungen/Reporting)

Alle Komponenten/Dienste werden genau einer dieser Kategorieen zugewiesen. Komponenten/Dienste dürfen nur auf andere Komponenten/Dienste zugreifen, wenn diese in einer niedrigeren Kategorie sind. Von Komponenten des Artikelstamms darf z.B. auf die Mandanten-Verwaltung oder die Server-Jobs zugegriffen werden, aber nicht auf Geschäftspartner, Einkauf oder Disposition. Zugegriffe müssen über RPC erfolgen. Greift eine Komponente/Dienst auf eine andere Komponente/Dienst zu, wird die abgewickelt, als würde z.B. ein Windows.Forms-GUI-Client auf die Komponente/Dienst zugreifen. Die Identität bzw die Sitzungsinformationen werden dabei mitgeschleift. Verkettete Dienstaufrufe verwendenalso normalerweise immer die Sitzung des ersten RPC-Aufrufers (Meistens ein GUI-Client). Dienste dürfen nür über definieirte Schnittstellen aufgerufen werden.
Komponenten/Dienste, die in der selben Assembly liegen, dürfen sich direkt aufrufen und müssen nicht über RPC gehen. Das ist wichtig, damit man Strukturierungsmöglichkeiten innerhalb der Geschäftslogik-Komponenten hat. Es ist auch von Vorteil, die eigentliche Implementierung der Geschäftslogik von der Kommunikations-Infrastruktur zu trennen. Mit Remoting geht das sehr gut. Die Dienst-Implementierung kümmert sich um Kommunikation und Aspekte wie Authentifizierung und delegiert den Aufruf anschließend an die eigentliche Logik-Implementierung. Diese muss dann auch nicht von MarshalByRef ableiten und kann bequem in einer separten Assembly untergebracht werden. Ich habe ein Architekturbeispiel gemacht, welches diese Konzept sehr schön zeigt: .NET Applikationsserver
Mit WCF kann man es genauso machen.
GUI-Clients jeder Art (also auch ASP.NET Seiten auf Webservern etc.) greifen immer über RCP zu. Bei Web ist das sogar besonders wichtig, da man das Web-Front-End so besser absichern kann.
Zitat von Golo Roden
- Wie würdet Ihr die Kommunikation über RPC aufbauen, insbesondere Events, die Rückmeldungen liefern?
So statuslos wie möglich! Je weniger statusbehaftet, desto skalierbarer. Wenn Du Serverfarmen unterstützen willst/musst, solltest Du die Sitzungen zwischen den Servern replizieren oder in der DB halten. Welche Metode die bessere ist, hängt vom Einzelfall ab. Eine Sitzung sollte so wenig Daten wie möglich enthalten. Bei mir ist das z.B. nur folgendes:
  • Sitzungsschlüssel (Guid)
  • Benutzeridentität (IIdentity)
  • Kultureinstellungen des Benutzers (CultureInfo x 2; 1 x UI; 1 x Env.)
  • Zeitstempel (Datetime)

Events würde ich vermeiden. Zur Beanchrichtigung für freigegebene Sperren, wenn ein Client darauf wartet und der Benutzer die schnellsmögliche Rückmeldung braucht, sind Events allerings fein. Ansonsten würde ich immer versuchen es ohne Events zu lösen.
Asynchrone Verarbeitung ist das Zauberwort für Automatisierbarkeit. Man sollte dem Server Aufträge (Jobs) in Warteschlangen stellen können, die er im Hintergrund abarbeitet. Asynchrone Verarbeiten ermöglicht auch den Einsatz einer Workflow-Engine wie z.B. WF.
Zitat von Golo Roden
- Was fehlt bei dem ganzen Ansatz?
Der bzw. die GUI-Client(s)! 80% des Aufwandes einer Geschäftsanwendung entfallen auf die Benutzeroberfläche. Der temporäre Status sollte beim GUI-Client liegen. Im Falle eines Web-Clients ist das der ASP.NET Sitzungsstatus bzw. Javascript im Browser. Besonders wenn Du verschiedene GUI-Clients anbieten willst/musst, solltest Du das in Deinem Entwurf berücksichtigen. Wenn Du z.B. einen GUI-Client für Windows Mobile oder für Handys (evtl. in Java geschrieben) haben willst, musst Du Dir bereits beim Entwurf Gedanken machen, wie solch ein Client mit der Geschäftslogik redet. Das Compact Framework kann z.B. kein Remoting und Java natürlich auch nicht. Die Frage, ob Du Deine Geschäftskomponenten/Dienste über unterschiedliche Endpunkte (z.B. binär TCP und HTTP SOAP) anbieten musst, hängt nicht zuletzt von der GUI-Client-Frage ab.
Zitat von Golo Roden
- Wo habe ich etwas grundlegendes vergessen?
Bei den folgenden Überlegungen gehe ich davon aus, dass Du eine Software schreibst und an Kunden im kompilierten Zustand auslieferst. Bei einer Inhouse-Anwendung treffen einige der Überlegungen nicht zu.
Wie kann die Anwendung später vom sachverständigen Endanwender erweitert und angepasst werden? Wie sieht es mit Add-Ins aus? Geschäftsprozesse ändern sich oft schneller, als ein Software-Anbieter reagieren kann. Deshalb sollte eine moderne Business-Anwendung Erweiterungsmöglichkeiten haben. Wenn nun bei jeder Lagerbuchung plötzlich eine Webservice einer Drittanwendung aufgerufen werden soll, muss das machbar sein, ohne den Lagerverwaltungsdienst anfassen zu müssen. Deshalb muss es Punkte in der Anwendung geben, die es einem Customizer oder Entwickler erlauben sich einzuhängen. Office ist ein gutes Beispiel. In Outlook oder Work kann ich Add-Ins und Makros schreiben. Das sollte auch für die Geschäftskomponenten/Dienste Deiner Anwendung möglich sein. Auch deshalb ist es ratsam Implementierung von Dienst und eigentlicher Geschäftslgik zu trennen. Die Dienst-Implementierung kann bei Bedarf konfigurierte Add-Ins oder sogar VB.NET/C#-Code laden und diesen an festgelegten Punkten die Kontrolle übertragen.
Deployment und Updates fallen mir da noch ein. Für mich ist das Teil der Architektur. Auch PlugIns etc. müssen auf Client- und ggf. auch auf die Server-Maschine(n) verteilt werden.
Wie werden Schnittstellen versioniert? Werden Client- und Server-Komponenten getrennt versioniert, oder eine Version für alle Assemblies des Anwendung? Ist ein Versionierung überhaupt nötig?
Wie wird die Datenbank bzw. deren Struktur versioniert? Wie können Anwender die DB erweitern, ohne die Updatefähigkeit zu verlieren?
private Nachricht | Beiträge des Benutzers
Khalid
myCSharp.de - Experte

Avatar #avatar-2534.gif


Dabei seit:
Beiträge: 3627
Herkunft: Hannover

beantworten | zitieren | melden

Hallo Rainbird

Sehr schöne detailierte Antwort.

Eine Frage dazu
Zitat
  • Infrastruktur-Dienste (Authentifizierung, Authorisierung, Sitzungsverwaltung, Server-Jobs, ...)
  • Basis-Dienste (Mandanten-Verwaltung, Verwaltung von Grunddaten wie Einheiten, Währungen, Zahlungsbedingungen, Textbausteinen ...)
  • Stammdaten-Dienste (Artikelstamm, Geschäftspartner, Preise, Lagerverwaltung)
  • Prozess-Dienste (Angebotswesen, Einkauf, Verkauf)
  • Kontroll-Dienste (Disposition, Auswertungen/Reporting)
Welche Dienste würden in diesen Falle direkt auf die Datenbank zugreifen? So wie ich es sehe wären es ja die ersten Drei, die direkt zugreifen, oder?

Ist jetzt nur rein aus Verständnis, weil ich es bei meinen Anwendungsserver zurzeit strikt einhalte, das nur ein einziger Dienst auf die DB zugreifen darf.
"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)
private Nachricht | Beiträge des Benutzers
Rainbird
myCSharp.de - Experte

Avatar #avatar-2834.jpg


Dabei seit:
Beiträge: 3953
Herkunft: Mauer

Nicht mit den Schichten verwechseln

beantworten | zitieren | melden

Zitat von Khalid
Welche Dienste würden in diesen Falle direkt auf die Datenbank zugreifen? So wie ich es sehe wären es ja die ersten Drei, die direkt zugreifen, oder?
Die Kategorieen haben nichts mit den Schichten zu tun! Es ist nicht so, dass die einzelnen Kategorieen bestimmten Schichten zugeordnet werden. Alle Dienste, dieser Kategorieen liegen in der Mittelschicht (Geschäftslogik).

Jeder Dienst greift direkt auf die Datenbank. Natürlich tut er das nicht unbedingt über ein direktes SqlCommand, sondern - wenn Abstraktion vom RDBMS für das Projekt wichtig ist - über eine Datenzugriffsschicht (Das könnte eine einfache Hilfsklasse sein, oder ein komplexes ADO.NET Entity Model mit Mappings und allem drum und dran).
Da verschiedene Dienste auch verschiedene Datenquellen haben können (Je größer das Projekt desto höher die Wahrscheinlichkeit, dass die Daten an verschiedenen Quellen liegen), würde ich den Datenzugriff nicht über einen zentralen Dienst schleusen, sondern die Datenzugriffsschicht direkt (also ohne RPC) innerhalb jedes Dienstes konsumieren.
Ich fasse außerdem Dienstschnittstellen und Datenstrukturen (in WCF würde man sagen DataContracts) pro Programmmodul in einer Contract-Assembly zusammen. Diese würde auch das ADO.NET Entity Model, die DataSets oder die Linq2SQL Klassen enthalten (Je nach eingesetzter Datenzugriffs-Technologie). Für die Architektur spielt das aber keine Rolle.
private Nachricht | Beiträge des Benutzers
Khalid
myCSharp.de - Experte

Avatar #avatar-2534.gif


Dabei seit:
Beiträge: 3627
Herkunft: Hannover

beantworten | zitieren | melden

Zitat
Die Kategorieen haben nichts mit den Schichten zu tun! Es ist nicht so, dass die einzelnen Kategorieen bestimmten Schichten zugeordnet werden. Alle Dienste, dieser Kategorieen liegen in der Mittelschicht (Geschäftslogik).
Ah OK. Dann ergibt das für mich jetzt alles wieder mehr Sinn
Ich habe das irgendwie anders interpretiert.
Zitat
Ich fasse außerdem Dienstschnittstellen und Datenstrukturen (in WCF würde man sagen DataContracts) pro Programmmodul in einer Contract-Assembly zusammen
So mach ich das auch.
"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)
private Nachricht | Beiträge des Benutzers
Sebi
myCSharp.de - Member



Dabei seit:
Beiträge: 169

beantworten | zitieren | melden

Hallo Rainbird,
in deiner Ausführung hast du Artikelstamm und Lagerverwaltung auf gleicher Ebene. Braucht aber nicht die Lagerverwaltung zugriff auf den Artikelstamm?
private Nachricht | Beiträge des Benutzers
Rainbird
myCSharp.de - Experte

Avatar #avatar-2834.jpg


Dabei seit:
Beiträge: 3953
Herkunft: Mauer

Artikelstamm und Lager

beantworten | zitieren | melden

Hallo Sebi,

das kann man so und so implementieren. Wenn in den Bestandsdatensätzen und damit auch für Buchungen nur die ArticleID benötigt wird, muss die Lagerverwaltung auch nicht auf den Artikelstamm zugreifen. Allerdings muss die GUI der Lagerverwaltung den Artikelstamm-Dienst konsumieren. Der Benutzer möchte natürlich detailierte Daten sehen.

Die Geschäftsdienste sind zwar autonom, aber sie werden von höheren Kategorieen aus und von Clients konsumiert und damit kombiniert. In diesem Modell muss man sich von der Vorstellung lösen, dass GUI-Client und Geschäftsdienste symmetrisch sind.

Die Anwendung besteht aus einer Sammlung von Diensten. Aus Hosting Sicht leben diese alle nebeneinander. Um die Abhängigkeiten im Griff zu haben, teilt man die Dieste in eine gedachte Hierarchie von Kategorien ein. GUI-Clients stehen ganz oben und dürfen theoretisch sämtliche Dienste Kreuz und Quer konsumieren. Die Dieste sind sozusagen das API der Business-Anwendung. Welche Dienste ein GUI-Client-Modul konsumieren darf ist eher eine Frage des Deployments und der Lizenzierung (Im Falle einer kommerziellen Anwendung)

Es wäre aber auch nicht falsch, fuer die Lagerverwaltung eine eigene Kategorie einzuschieben. Die Kategorieen sind ja nur gedacht und verursachen an sich keinen Aufwand.
private Nachricht | Beiträge des Benutzers
Sebi
myCSharp.de - Member



Dabei seit:
Beiträge: 169

beantworten | zitieren | melden

Hallo,
das heißt dann arbeiten die Dienste mit den weiter oben erwähnten Entities welche dann in ner höheren Ebene die Zugriff auf die entsprechenden Dienste hat zu Business Objekten zusammengebaut werden?
private Nachricht | Beiträge des Benutzers
Rainbird
myCSharp.de - Experte

Avatar #avatar-2834.jpg


Dabei seit:
Beiträge: 3953
Herkunft: Mauer

Kontrakte

beantworten | zitieren | melden

Hallo Sebi,

was meinst Du genau mit Business Objekten? Der Begriff ist ein wenig schwammig.

Nicht in Schichten denken! Geschäftslogik, Dienste, Dienstschnittstellen und Datenstrukturen liegen alle zusammen in der Mittelschicht. Die Datenstrukturen werden von Geschäftslogik und Diensten gemeinsam genutzt. Im WCF-Jargon würde man Datenstrukturen DataContracts bzw. MessageContracts nennen. Vom ADO.NET Entity Framework erzeugte Objekte sind übrigens automatisch DataContracts.
Es könnten aber auch beliebige serialisierbare Objekte sein (z.B. DataSets/DataTables). Das spielt aber nicht wirklich eine Rolle.
private Nachricht | Beiträge des Benutzers
Omit
myCSharp.de - Member

Avatar #avatar-2748.jpg


Dabei seit:
Beiträge: 146

beantworten | zitieren | melden

Hi Leute,
Zitat von Golo
Bereits hier sollte mit Transaktionen gearbeitet werden, zudem bietet sich in der unteren Schicht evtl der Einsatz eines O/R-Mappers an. Auch Locking sollte hier in den grundlegenden Funktionen verfügbar sein, sprich Datensatz sperren, Datensatz entsperren, usw ...
Zitat von Rainbird
Transaktionen müssen ja erst aufgespannt werden. Verschiedene Komponenten können an einer Transaktion beteiligt sein. Die Datenzugriffsschicht kann das nicht leisten, da es vom Geschäftsprozess abhängig ist, welche Operationen zusammen in einer Transaktion ausgeführt werden müssen. Deshalb haben Transaktion in der Datenzugriffsschicht eigentlich nix verloren. Aber auch das ist bereits mit System.Transactions gelöst. ADO.NET, LINQ2SQL und Entity Framework unterstützen System.Transactions-Transaktionen.

korrigiert mich, wenn ich falsch liege...

Ich würde sagen, irgendwie habt ihr beide recht und ihr widerlegt euch ja auch nicht gegenseitig.
Wie es schon Golo sagt, wäre auch meine Intention, in den Datenzugriffslogiken Transaktionen aufzuspannen. Denn die Aufgabe von diesen ist es ja, auch aus (möglichen) mehreren Datenquellen, die Entities zusammen zu setzten und wieder abzuspeichern. Da dies auch über mehrere Abfragen geschehen kann, müssen klar auch schon hier Transaktionen zum Einsatz kommen.

Rainbird du hast zwar Recht, dass Geschäftsprozesse Transaktionen über mehrer Entities aufspannen müssen, aber es spricht ja nichts dagegen besetehende Transaktionen nochmals zu verpacken.

Ansonsten finde ich beide Ausführungen sehr interessant!

Gruß Timo
private Nachricht | Beiträge des Benutzers
Rainbird
myCSharp.de - Experte

Avatar #avatar-2834.jpg


Dabei seit:
Beiträge: 3953
Herkunft: Mauer

Transaktionen

beantworten | zitieren | melden

Hallo Omit,

natürlich kann man Transaktionen schachteln. Wenn die Datenzugriffsschicht allerdings generell alles in Transaktionen packt, hat man z.B. ein Problem, wenn eine bestimmte Operation nicht in einer Transaktion ablaufen soll. Wenn die Datenzugriffsschicht die Transaktionen nicht automatisch macht und man sie manuell aufrufen muss, kann man auch gleich alles in der Geschäftslogik mit System.Transactions machen.

Bei langlaufenden oder anwendungsübergreifenden Geschäftsprozessen müssen statt atomarer Transaktionen eh Sagas (http://www.serviceoriented.org/long_running_transactions.html) zum Einsatz kommen. Spätestens bei solchen Sachen (die bei jeder größeren Business-Anwendung früher oder später auftreten) ist es nicht mehr sinnvoll, die Transaktionslogik auf Geschäfts- und Datenzugriffsschicht zu versteuen.

Trotzdem kann es natürlich Projekte geben, bei denen es Sinn macht, Transaktionen auch direkt in der Datenzugriffsschicht aufzuspannen (Pauschalaussagen sind nämlich generell mit vorsicht zu genießen). Nach meiner Erfahrung ist es aber - zumindest für Business-Applikationen - nicht optimal.

WF-Workflows eignen sich übrigens auch sehr gut, um Transaktionen in Geschäftsprozessen einzubringen. Mit den Workflow Services (WF über WCF) können so auch gut externe Anwendungen angekoppelt werden.
private Nachricht | Beiträge des Benutzers
Omit
myCSharp.de - Member

Avatar #avatar-2748.jpg


Dabei seit:
Beiträge: 146

beantworten | zitieren | melden

Mit Long Running Transactions hab ich mich noch nicht beschäftigt. Deshalb habe ich eine Frage:
Zitat
Long Running Transactions (LRT, also known as Sagas) are transactions that may take minutes, days or weeks before the outcome of the transaction is known.
Verstehe ich das richtig, dann sind alle Ressourcen solang gesperrt, oder wie realisiert man so eine Transaktion? Oder muss man dann alles einzeln wieder zurück aufdröseln?

Ach danke für http://www.serviceoriented.org/ , kannte ich noch nicht und scheint wirklich sehr gut zu sein. Nach meiner Klausur, werde ich mich da durchackern *freu*, kann mich kaum zurück halten(Timo NACH der Klausur *g)!

Gruß TimoW
Dieser Beitrag wurde 3 mal editiert, zum letzten Mal von Omit am .
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 52329
Herkunft: Berlin

beantworten | zitieren | melden

Hallo Omit,
Zitat
Verstehe ich das richtig, dann sind alle Ressourcen solang gesperrt, oder wie realisiert man so eine Transaktion?
typischerweise würde man dann nicht pessimistisch sperren, sondern ein ==> optimistisches Sperrverfahren verwenden.

herbivore
private Nachricht | Beiträge des Benutzers
Omit
myCSharp.de - Member

Avatar #avatar-2748.jpg


Dabei seit:
Beiträge: 146

beantworten | zitieren | melden

OK danke, war mir jetzt ganz entfallen. Aber klar. Muss mich damit nochmal auseinandersetzten!

Gruß Timo
private Nachricht | Beiträge des Benutzers
_daniel_
myCSharp.de - Member



Dabei seit:
Beiträge: 229

beantworten | zitieren | melden

Hallo
wo würdet ihr in einer solchen SOA Umgebung die Prüfung einordnen die das löschen eines Mandanten verbietet wenn noch offene Aufträge existieren?
private Nachricht | Beiträge des Benutzers
Rainbird
myCSharp.de - Experte

Avatar #avatar-2834.jpg


Dabei seit:
Beiträge: 3953
Herkunft: Mauer

Dienstekategorieen

beantworten | zitieren | melden

Hallo _daniel_,

ausgehend davon, dass die Dienste der Applikation in Kategorieen eingeteilt wurden und in einer gedachten Hierarchie angeordnet sind, kannst Du die Prüfung nicht direkt im Mandantenverwaltungsdienst machen, da der Mandantenverwaltungsdienst vermutlich in einer niedrigeren Kategorie ist als der Dienst zur Auftragsabwicklung.
Also muss man auf höherer Ebene einen Dienst einziehen, der solche Workflows kapselt (ich nenne den jetzt einfach mal Workflow-Dienst). Den Löschbefehl willst Du zwar über den Mandantenverwaltungsdienst geben, aber die Prüfung darf nicht direkt in diesem Dienst gemacht werden. Der Workflow-Dienst muss also irgendwie mitbekommen, dass jemand einen Mandanten löschen will. Damit das geht, muss der Mandantenverwaltungsdienst die Möglichkeit bieten, dass man per Konfiguration andere Dienste als Empfänger von Nachrichten bei bestimmten Ereignissen konfigurieren kann. Es funktioniert dann vom Prinzip her, wie bei einem FormClosing-Ereignis in Windows.Forms. Bei diesem Ereignis kann man mittels e.Cancel=true dem FOrmular mitteilen, dass das Schließen abgebrochen wird. Genauso könnte der Workflowdienst per Abo vom Mandantenverwaltungsdienst benachrichtigt werden, dass ein Mandant gelöscht werden soll. Der Workflow-Dienst führt die Prüfung durch (konsumiert dazu den Dienst zur Auftragsabwicklung) und sendet dem Mandantenverwaltungsdienst eine Nachricht zurück, ob Abgebrochen werden soll, oder nicht. Wichtig dabei ist, dass die Kommunikation entkoppelt abläuft. Der Mandantenverwaltungsdienst darf weder die Schnittstelle noch die Implementierung des Workflow-Dienstes kennen.

Man sollte sich bei so einer Situation auch Gedanken machen, ob das alles synchron oder asynchron ablaufen soll. Je größer die Anwendung, desto eher würde ich alles asynchron machen.

So ein lose gekoppeltes Ereignissystem ist auch bei vielen anderen Dingen nützlich, da man die Abgebildeten Geschäftsprozesse so ändern und beeinflussen kann, ohne laufende fertige Dienste anzufassen. Das macht unterm Strich eine schnellere Reaktionszeit auf Änderungen am Geschäftsprozess.
private Nachricht | Beiträge des Benutzers
_daniel_
myCSharp.de - Member



Dabei seit:
Beiträge: 229

beantworten | zitieren | melden

Hallo,
das heißt der Client arbeitet nur mit den Workflows welche dann wiederrum mit den Diensten kommunizieren oder die Workflows "überwachen" praktisch die Arbeit der Dienste?
private Nachricht | Beiträge des Benutzers
Rainbird
myCSharp.de - Experte

Avatar #avatar-2834.jpg


Dabei seit:
Beiträge: 3953
Herkunft: Mauer

Keine Schichten

beantworten | zitieren | melden

Hallo _daniel_,

Der Workflowdienst überwacht den Mandantenverwaltungsdienst in diesem Fall. Wenn der Client einen Mandanten löschen will, dann tut er das über den Mandantenverwaltungsdienst. Der Mandantenverwaltungsdienst stellt seinerseits einen Publish-Subscribe-Mechanismus zur Verfügung, damit andere Dienste/Komponenten "Ereignisse" abonnieren und sich in die Verarbeitung einschalten können. Der Workflowdienst wird nicht direkt vom Client aufgerufen, sondern vom Mandantenverwaltungsdienst benachrichtigt, dass ein Mandant gelöscht werden soll. Der Mandantenverwaltungsdienst kennt den Workflowdienst aber nicht! Genauso wie ein Button nicht das Form kennt, welches sein Click-Ereignis behandelt.

Wenn der Client den Mandnatenlöschbefehl direkt über den Workflowdienst laufen würde, müsste dieser alle Operationen des Mandantenverwaltungsdienstes kapseln. Das ist ein Schichtendenken, das an dieser Stelle nur Nachteile bringt. Die API der Applikation wäre dadurch nicht mehr intuitiv. Wenn ich einen Mandanten löschen will, liegt es nahe, dies über den gleichnahmigen Dienst zu tun.
private Nachricht | Beiträge des Benutzers
_daniel_
myCSharp.de - Member



Dabei seit:
Beiträge: 229

beantworten | zitieren | melden

Hallo,
danke für die Erläuterungen.

Wie würden Workflows der Workflow Foundation in das Konzept passen?
private Nachricht | Beiträge des Benutzers
Rainbird
myCSharp.de - Experte

Avatar #avatar-2834.jpg


Dabei seit:
Beiträge: 3953
Herkunft: Mauer

Wf

beantworten | zitieren | melden

Hallo _daniel_,

die würden sehr gut passen. Im .NET Framework 3.5 gint es die sog. Workflow Services. Das ist eine Technologie, die es realtiv einfach ermöglicht, WF-Workflows direkt als WCF-Dienste zu hosten. Für den Aufrufer sehen die Workflows aus, wie ganz gewöhnliche WCF-Dienste. Für Diese, die längerandauernde Abläufe abbilden, sind WF-Workflows ideal. Besonders langlaufende Transaktionen (Sagas) lassen sich mit WF grafisch entwerfen. Die wichtigsten Activities bringt WF schon mit.
Man sollte den Aufwand WF-Workflows zu erstellen und diue Einarbeitungszeit allerdings nicht unterschätzen. WF ist komplex und aufwändig! Auch über das Deployment muss man sich Gedanken machen. Für gewöhnlich möchte man Workflows kurzfristig anpassen können, ohne eine komplett neue Programmversion ausrollen zu müssen. Geänderte Workflows müssen ihren Weg auf den Applikationsserver finden.
Wenn die Infrastruktur für das Hosting von WF-Workflows in den eigenen Anwendungen mal steht, hat man sich mit Sicherheit jede Menge Vorteile eingekauft. Man sollte es - wie mit allem - auch mit den Workflows nicht übertreiben. Einsetzen, wo sinnvoll, ansonsten lassen.
private Nachricht | Beiträge des Benutzers
_daniel_
myCSharp.de - Member



Dabei seit:
Beiträge: 229

beantworten | zitieren | melden

Hallo,
zumal die neue Version mit den alten wohl nicht ganz kompatibel ist.

Heißt es in diesem fall dann dass der Client mit den Workflows abeitet? Oder auch hier nur indirekt über Events der Services?
private Nachricht | Beiträge des Benutzers
Rainbird
myCSharp.de - Experte

Avatar #avatar-2834.jpg


Dabei seit:
Beiträge: 3953
Herkunft: Mauer

Workflows

beantworten | zitieren | melden

Hallo _daniel_,

Workflows sind ein weites Feld und sehr vielseitig einsetzbar. Es ging ursprünglich ja um den konkreten Fall, dass vor der Löschung eines Mandanten geprüft werden muss, ob noch Aufträge unter diesem Mandanten existieren. Die Prüfung darf die Mandantenverwaltung allerdings nicht direkt durchführen, da dies zu einer zirkulären Abhängigkeit zwischen Mandanten- und Auftragsverwaltung führen würde. In diesem konkreten Fall könnte man das sehr elegant lösen, in dem ein als Workflow implementierter Dienst die Mandantenverwaltung überwacht (bzw. von dieser informiert wird).

Das heißt nicht, dass das immer der beste Weg ist. Mit WF können sowohl langlaufende (also z.B. über Stunden, Tage, Wochen oder sogar Jahre) als auch kurzlaufende Workflows abgewickelt werden. Man könnte einen WF-Workflow durchaus innerhalb eines Windows.Forms-Clients einsetzen, um zu steuern wann welche Knöpfe auf Menü- und Symbolleisten ausgegraut werden und wann nicht. Man kann aber auch ein großes Geschäft - welches über Monate läuft - inklusive Beschaffung, Terminierung, Auslieferung, Zahlung, Reklamation etc. über einen komplexen Workflow steuern.

Wenn Menschen in einen Workflow direkt eingebunden sind (um z.B. Eingaben zu machen oder etwas zu genehmigen bzw. abzulehnen) ist es sinnvoll, dass Clients direkt mit einzelnen Workflow-Instanzen kommunizieren. Mittels Hosting in Workflow Services und SOAP-Kommunikation lassen sich so vor allem auch fremde Applikationen in Workflows einbinden (man denke z.B. an InfoPath).

Es kommt auf die konkreten Geschäftsprozesse an, die abgebildet werden sollen, ob und in welcher Form Workflows vorteilhaft sein. Eine pauschale Aussage gibt es da nicht. Wichtig ist, dass man die Geschäftsprozesse , die man als Software umsetzen möchte selbst sehr gut kennt auch versteht. Mangelndes Wissen und Verständnis über die Problemdomäne ist bei Software-Entwicklen generell ein Problem. Es scheint of viel interessanter zu sein, an der perfekten OR-Mapping-Implementierung zu feilen, statt sich mit den Problemen der Fachabteilungen rumzuärgern. Die Software-Architektur muss aufgrund der abzubildenden Geschäftsprozesse festgelegt werden.

Was für Geschäftsprozesse willst/musst Du denn umsetzen?
private Nachricht | Beiträge des Benutzers
_daniel_
myCSharp.de - Member



Dabei seit:
Beiträge: 229

beantworten | zitieren | melden

Hallo,
bei mir geht es in die Richtung die ich angeschnitten habe mit Mandant, Angebot,Auftrag, Bestellung, Lager usw.

Das verstehen der Prozesse sehe ich auch als enorm wichtig.
Überlegt hatte ich zwei Richtungen
1. ein Workflow geht vom Erstellen eines Angebots über die Komplettierung bis zum "Ausgabe"
und (oder)
2. ein Workflow geht vom Angebot über den Auftrag zur Lieferung. Wobei hier in regelmäßigen Abständen alle die bei Angebot hängen rausfliegen.


Allgemein habe ich mich für eine Servcie-orientierte Architektur entschieden weil verschiedene Services noch an anderen Stellen benötigt werden z.b. Kontaktdaten für die Telefonanlage und Exchange, kleinere Anwendungen in der Produktion sowie Lager.
Wobei ich hier noch nicht ganz sicher bin wie ich die Services am besten hoste. Erste überlegungen gehen wohl richtung Windows Service da ich hier zentrale dinge wie logging und caching habe. Alternativ könnte jeder Service sein eigenes Caching haben.


Haupt-Client seitig ist es eine modularen Anwendung die das Composite WPF von p&p nutzt.
private Nachricht | Beiträge des Benutzers
Rainbird
myCSharp.de - Experte

Avatar #avatar-2834.jpg


Dabei seit:
Beiträge: 3953
Herkunft: Mauer

Angebote & Lieferung/Rechnung

beantworten | zitieren | melden

Hallo _daniel_,

ich würde den Lead/Anfrage/Angebots-Workflow vom Auftrags-Workflow trennen. In Auftragserfassung/Lieferung und Rechnungswesen ändert sich der Ablauf eher selten. Bei Vetriebs-Ablufen, wie Angeboten, ist damit zu rechnen, dass sich häufiger etwas am Ablauf ändert oder neue Geschäftsregeln zusätzlich installiert werden.

Was meist Du mit Caching? Was sollen die Dienste denn genau cachen?
private Nachricht | Beiträge des Benutzers