Fragen zur Software-Architektur

"Transport Timm liefert 10 Büchsen Farbe von "Bunt& Klar", 5 Rollen Kabel von "Elektro-Meier" und 5 Kisten Schrauben von "Schrauben-Paul". Diese Dinge werden in die Lagerfächer 1 bis 3 einsortiert.
Möglicherweise hast du doch recht damit, dass es nicht vollständig abgedeckt ist. Korrekt wäre, dass der Mitarbeiter, der die Einlagerung vornimmt, nach der offenen Bestellung sucht und diese im Zuge der Einlagerung abschließt. Das möchte ich aber erst mal verschieben, damit es nicht zu umfangreich wird an dieser Stelle.

Aber ich sehe das möglicherweise in einem anderen BoundedContext, oder? Möglicherweise sollte sogar Supplier, Manufacturer, Adress und Contact aus dem Kontext der Materialverwaltung entfernt werden. Ich habe das für die Documentation schon mal angedeutet. Wie seht ihr das?
 
Evtl. habe ich falsch übersetzt/interpretiert. Kannst Du (ggf. nochmal?) kurz schreiben, was StorageLocation und MaterialStock sein soll?
 
Evtl. habe ich falsch übersetzt/interpretiert. Kannst Du (ggf. nochmal?) kurz schreiben, was StorageLocation und MaterialStock sein soll?
Mach ich gern.
StorageLocation = Lagerort, z.B. Werkstatt EG, Werkstatt KG, Lager OG. I.d.R. werden die einmal am Anfang festgelegt und ändern sich dann nicht mehr.
MaterialStock = Lagerbestand mit Angabe des Lagerplatzes (z.B. Schrank 10 / Fach 3) bezogen auf einen bestimmten Lagerort.

Ein Material kann also mehrere Lagerbestände haben, die an unterschiedlichen Lagerorten untergebracht sind.

Im Diagramm ist da noch ein Fehler: Ein MaterialStock hat keinen "shortName" und keine "description".

Außerdem könnte theoretisch das Feld "amount" auch weggelassen werden, weil dieser aus den (noch so genannten) "PostTransactions" berechnet werden könnte. Ob das aber sinnvoll ist?
 
StorageLocation = Lagerort, z.B. Werkstatt EG, Werkstatt KG, Lager OG. I.d.R. werden die einmal am Anfang festgelegt und ändern sich dann nicht mehr.
MaterialStock = Lagerbestand mit Angabe des Lagerplatzes (z.B. Schrank 10 / Fach 3) bezogen auf einen bestimmten Lagerort.
Gut, dann habe ich das schon richtig verstanden 🙂 und es gilt, was ich oben geschrieben habe: zwischen StorageLocation und MaterialStock gibt es eine 1:n-Beziehung.
 
Zuletzt bearbeitet von einem Moderator:
Gut, dann verstehe ich dich nicht. 🙁
An jeder StorageLocation gibt es mehrere MaterialStocks, jedes MaterialStocks ist aber in/gehört zu/wahtever einer StorageLocation:
StorageLocation <>-1--*- MaterialStocks


Außerdem könnte theoretisch das Feld "amount" auch weggelassen werden, weil dieser aus den (noch so genannten) "PostTransactions" berechnet werden könnte. Ob das aber sinnvoll ist?
Felder im Domänenmodell müssen nicht eins-zu-eins Feldern in den Klassen entsprechen 😉
MMn kann man das auch mit dieser Lösung umsetzen und entspricht trotzdem dem Modell.
 
Zuletzt bearbeitet:
An jeder StorageLocation gibt es mehrere MaterialStocks, jedes MaterialStocks ist aber in einer StorageLocation:
StorageLocation <>-1--*- MaterialStocks

MaterialStock ist in keiner StorageLocation

locationstock.png
Nicht ausgefüllte Raute = Aggregation

Die StorageLocation kann auch ohne einen MaterialStock bestehen. Der MaterialStock benötigt eine StorageLocation.

https://de.wikipedia.org/wiki/Klassendiagramm#Komposition_und_Aggregation

?

Ihr werft gerade mein ganzes Weltbild durcheinander 🙂
 
Ja, in diesem Fall wäre aber Komposition besser (MaterialStock gibt es nicht ohne StorageLocation existieren) und die Beziehung müsste andersrum als in deinem Modell sein.
Ich glaub ich trink jetzt erst mal ein Bier 😉

Also was ich ausdrücken möchte ist folgendes und ich formuliere es jetzt mal als Klasse:

Die Klasse MaterialStock enthält ein Feld vom Typ StorageLocation. Die Klasse StorageLocation weiß von MaterialStock gar nichts.

Was muss ich jetzt also dahin malen?

Komposition:
Wikipedia hat gesagt.:
Existenzabhängigkeit bedeutet, dass das Ganze den Lebenszyklus der Teile bestimmt, d. h. das Objekt, welches das Ganze repräsentiert, übernimmt auch die Verantwortung für die Lebensdauer der Objekte, die seine Teile repräsentieren. Wird das Ganze gelöscht, verschwinden auch die Objekte, die zu diesem Zeitpunkt Bestandteil waren.

Darum hab ich Aggregation genommen, denn die StorageLocations existieren auch, wenn es überhaupt keine MaterialStocks gibt.

Lass ich einfach alle Rauten weg, dann habe ich eine Assoziation.
 
Also was ich ausdrücken möchte ist folgendes und ich formuliere es jetzt mal als Klasse:

Die Klasse MaterialStock enthält ein Feld vom Typ StorageLocation. Die Klasse StorageLocation weiß von MaterialStock gar nichts.
Das ist nicht das was du ausdrücken möchtest, sondern wie du es implementieren würdest 😉
Man macht es sich deutlich einfacher, wenn man solche Implementierungsdetails aus dem Modell ableitet, und nicht vorher festlegt und das Modell danach entwickelt, uU hat man dann nämlich völlig falsche Vorstellungen und macht es deutlich komplizierter als nötig.

Rein von dem Modell ausgehend würde ich es uU sogar andersrum implementieren, also Liste in StorageLocation 😉

Darum hab ich Aggregation genommen, denn die StorageLocations existieren auch, wenn es überhaupt keine MaterialStocks gibt.
Generell richtig, aber deine Aggregation drückt aktuell aus, das ein MaterialStock eine Aggregation von StorageLocations ist, also umgangssprachlich ein MaterialStock mehrere StorageLocations enthält.

Was du eigentlich meinst ist doch das Gegenteil: eine StorageLocations enthält mehrer eingelagerte Dinge (=Beziehung muss andersrum), und die MaterialStocks gibt es nur in einer StorageLocations, MaterialStock kann es nicht unabhängig davon geben (= Komposition).



Zum Modellieren würde mir das reichen:
Untitled Diagram.png
Kardinalitäten würde ich dabei nur ergänzen, wenn sie nicht 1:n entsprechen.
 
Es ist nicht einfach, nicht in Implementierungen zu denken, weil man sich im Hinterkopf fast immer überlegt, wie die Klassen und DB-Tabellen dazu aussehen könnten. In der Tat sind "meine" Domänenobjekte fast 1:1 aus meinen Gedanken zur Datenbank entsprungen (was ja einige Beiträge weiter vorne bereits mit Recht kritisiert wurde).

Was du eigentlich meinst ist doch das Gegenteil: eine StorageLocation enthält mehrere eingelagerte Dinge

Müsste ich bei dieser Formulierung: "Ein Lager enthält mehrere eingelagerte Materialien" nicht ganz naiv so beginnen?

locationmaterial.png

MaterialStock ist ja bereits ein Detail, das sich aus der Datenbank-Normalisierung ergeben hat (würde).

Wobei dann Komposition wieder falsch wäre, denn beide können zunächst mal unabhängig voneinander existieren, bis dem Material ein Lager zugeordnet wird.
 
Zuletzt bearbeitet:
Vielen Dank übrigens noch einmal an alle, die sich an dieser, für mich sehr angenehm verlaufenden und äußerst lehrreichen Diskussion beteiligen! Ich nehme viele für mich sehr wertvolle Informationen mit.

🙂🙂🙂🙂🙂🙂🙂🙂🙂🙂🙂🙂🙂🙂🙂🙂
 
Es ist nicht einfach, nicht in Implementierungen zu denken, weil man sich im Hinterkopf fast immer überlegt, wie die Klassen und DB-Tabellen dazu aussehen könnten. In der Tat sind "meine" Domänenobjekte fast 1:1 aus meinen Gedanken zur Datenbank entsprungen (was ja einige Beiträge weiter vorne bereits mit Recht kritisiert wurde).
Kenn ich, dass das manchmal schwierig ist 😉

Man muss es einfach immer wieder mal wegschieben, wenn man drüber nach denkt.
Mir wurde mal gesagt; Modellieren ist das schwierige, Implementiert bekommt man alles.

Und wenn du jetzt jemandem ohne Programmierkenntnisse das Modell erklären sollst, wird der dich bei „MaterialStock hat ein Feld von StorageLocation“ ziemlich dumm angucken - dabei ist das Verständis eigentlich der wesentliche Punkt 😉

Müsste ich bei dieser Formulierung: "Ein Lager enthält mehrere eingelagerte Materialien" nicht ganz naiv so beginnen?

locationmaterial-png.11110


MaterialStock ist ja bereits ein Detail, das sich aus der Datenbank-Normalisierung ergeben hat.
Ja, würde man wahrscheinlich - deshalb entwickelt man es iterative weiter 😉

Dabei fällt nämlich auf, das man jetzt gar keine Informationen über Mengen und Positionen, und man würde rein aus der Domäne schon ein zusätzliches Element dazwischen einfügen.
Es gibt ja auch in nem echten Lager mehr als nur das Lager und die Dinge die dein liegen. Vermutlich würd dann irgendein Lagerarbeiter drauf hinweisen, dass es eine Liste gibt, in der drin steht, wie viel wovon wo liegt oder so

Vielen Dank übrigens noch einmal an alle, die sich an dieser, für mich sehr angenehm verlaufenden und äußerst lehrreichen Diskussion beteiligen! Ich nehme viele für mich sehr wertvolle Informationen mit.
Für mich ist das auch lehrreich - es gibt keine Diskussionen, bei denen man nicht selbst auch was lernen würde 😉

Und grad Domänenmodelle kann man nur echt schwierig allein entwickeln, da ist sowas schon echt nötig 😉
 
Gut, wieder zurück zu den Wurzeln. Ich habe erst mal alles wieder etwas reduziert.

dom_material.png

  • Ein Material hat eine Mengeneinheit zur Kalkulation der Bestände.
  • Ein Material kann mehrere Bestände (in verschiedenen Lagern) enthalten.
  • Es gibt ein oder mehrere unterschiedliche Lager.
  • Ein Lager kann Bestände von unterschiedlichen Materialien enthalten.
  • Die Bestände eines Materials können durch eine Transaktion geändert werden.
Ist das so einigermaßen korrekt modelliert?

Ist es sinnvoll den Kontext nur auf die Lagerhaltung des Materials zu begrenzen?

(Edit: Eine bessere Begrifflichkeit wäre vielleicht der der Teildomäne.)

Zum Material gehören noch weitere Daten, wie Lieferant, Hersteller, Hersteller-Materialnummer, die für das Material und für die Ein- und Auslagerung von Material nicht relevant sind. Diese würde ich daher in einen (oder mehrere) anderen Kontext (Edit: Teildomäne), z.B. "Order" verschieben.

Damit gehe ich für heute zum gemütlichen Teil über und wünsche euch allen noch einen angenehmen Sonntag!
 
Zuletzt bearbeitet:
Wenn ich jetzt rein OO denke, dann habe ich diese Beziehungen:

Ein Lager enthält eine Liste seiner Lagerfächer.
Ein Lagerfach enthält die Art und die Anzahl der in ihm gelagerten Dinge.
Ein Lagerfach kann nur ein Material enthalten.
Ein Material kann sich in mehreren Lagerfächern befinden.
Ein Lager enthält eine Liste seiner Zweigstellen.
Eine Zweigstelle enthält eine Liste der Lagerfächer, die in ihr sind.

Das ist aber "falschherum":

Es müsste so sein:
Ein Lager enthält eine Liste der abgelegten Materialien.
Ein Material enthält eine Liste der Lagerfächer, wo es abgelegt ist
Ein Lagerfach kennt seinen Bestand an dem abgelegten Material.
Ein Lager enthält eine Liste seiner Zweigstellen.
Eine Zweigstelle enthält die Liste der Lagerfächer, die in ihm liegen.
 
Es müsste so sein:
Ein Lager enthält eine Liste der abgelegten Materialien.
Ein Material enthält eine Liste der Lagerfächer, wo es abgelegt ist
Ein Lagerfach kennt seinen Bestand an dem abgelegten Material.
Ein Lager enthält eine Liste seiner Zweigstellen.
Eine Zweigstelle enthält die Liste der Lagerfächer, die in ihm liegen.
Da ich in diesem Fall der Domänenspezialist bin (😉), kann ich dir an dieser Stelle sagen, dass es bei uns keine Zweigstellen gibt. Außerdem werden Bestände von Material nur auf Lagerort-Ebene betrachtet, nicht auf Lagerplatz-Ebene.

Da wir beide ja das gleiche Buch gelesen haben, habe ich die Begriffe der ubiquitären Sprache fett markiert. 😉

Mir fällt aber gerade auf, dass ich mich in #64 auch nicht dran gehalten habe. Böse.
 
Zuletzt bearbeitet:
Hast du jemals irgendetwas in der Hand gehabt, und da stand drauf "ich liege in Fach 37A"?
Es ist wirklich schwierig abzuschalten, wenn man sich gerade auf der Zielgerade wähnt...

Dein Kommentar hat mich dazu gebracht noch einmal nachzudenken.
Ein Material kann mehrere Bestände (in verschiedenen Lagern) enthalten.
Das klingt irgendwie falsch, weil ein Material keine Bestände enthält so wie es keine "Ablagefächer" enthält und damit wäre auch die Beziehung von Material zu Bestand (MaterialStock) falsch.
  1. Ein Material hat eine Mengeneinheit zur Kalkulation der Bestände.
  2. ?
  3. Es gibt ein oder mehrere Lagerorte.
  4. Ein Lagerort enthält Bestände von unterschiedlichem Material.
  5. Bestände werden durch Ein- und Auslagerungen verändert
Vielleicht ist 2. auch nicht notwendig, weil bereits durch 4. abgedeckt. Wie ist aber die Beziehung zwischen Material und Bestand?
 
Es ging mir vor allem um die Modellierung der Beziehungen zwischen den Objekten und Klassen.

So wie ich den TE verstanden habe, möchte der Bearbeiter wissen, wo welche Materialien liegen. Dabei war es für mich logisch, dass die Suchkette damit beginnt, dass in einem Objekt Lager, dem "Root-Objekt", eine Suche nach dem Material durchgeführt wird. Deshalb benötigt dieses Objekt Lager doch eine Liste der abgelegten Materialien (Klasse Material). In diesem Sinne wäre es doch schlau, wenn das Objekt Material eine Liste der Lagerplätze enthält, wo Bestände dieses Materials abgelegt ist. Suche ich "Waschbenzin", dann bekomme ich raus, dass "30 Liter an Stelle A3 " und "50 Liter auf an Stelle B4" sind. Ich habe auch überlegt, diesen Plätzen die Standorte (Boden, Werkstatt, Keller) zuzuordnen, aber ich bin dabei auf der n-Seite einer 1:n-Beziehung. Und das fand ich nicht so gut. Daher war ich dazu übergegangen, dass die Klasse Lager eine Liste der Standorte enthält, die wiederum die Liste der Lagerplätze enthält, die bei ihm sind.

Nun ist es recht egal, ob A3 (oder B4) eine abgekreidete Fläche beschreibt oder ein Fach in einem Schrank. Das ist zuerst zwar etwas umständlich umzusetzen, denn der Gabelstapler ist ja einfach da, aber dem muss trotzdem ein Standort zugewiesen werden, sonst platzt das Modell.

Wenn der Lagerist weiß, dass sich 5 Kisten Schrauben M5x60 auf dem Boden befinden, dann hilft dem das wenig, wenn es dort 300 Meter Lagerfläche gibt. Das wäre schon die Suche einer Stricknadel im Heuhaufen. Ich glaube, da wäre dann eine genauere Festlegung des Ortes besser.
 
Wie ist aber die Beziehung zwischen Material und Bestand?
In dem Fall würde ich nur die Aggregation streichen (ist mir zugegebenerweise auch gar nicht aufgefallen, die ist so klein und versteckt...) und stattdessen an der Seite ein "1" ergänzen.

Es ging mir vor allem um die Modellierung der Beziehungen zwischen den Objekten und Klassen.
Relevant ist aber, dass es "konzeptionelle Klassen", und keine Klassen im Sinne des Java-Klassenbegriffs sind 😉


So wie ich den TE verstanden habe, möchte der Bearbeiter wissen, wo welche Materialien liegen. Dabei war es für mich logisch, dass die Suchkette damit beginnt, dass in einem Objekt Lager, dem "Root-Objekt", eine Suche nach dem Material durchgeführt wird. Deshalb benötigt dieses Objekt Lager doch eine Liste der abgelegten Materialien (Klasse Material). In diesem Sinne wäre es doch schlau, wenn das Objekt Material eine Liste der Lagerplätze enthält, wo Bestände dieses Materials abgelegt ist. Suche ich "Waschbenzin", dann bekomme ich raus, dass "30 Liter an Stelle A3 " und "50 Liter auf an Stelle B4" sind. Ich habe auch überlegt, diesen Plätzen die Standorte (Boden, Werkstatt, Keller) zuzuordnen, aber ich bin dabei auf der n-Seite einer 1:n-Beziehung. Und das fand ich nicht so gut. Daher war ich dazu übergegangen, dass die Klasse Lager eine Liste der Standorte enthält, die wiederum die Liste der Lagerplätze enthält, die bei ihm sind.
Das hat man doch bis auf unterschiedliche Lagerorte in einem Lager in seinem Modell schon gegeben.
Zwar nicht als direkte Beziehung, das wäre aber auch unsinnig und nur Redundanz.

Unterschiedliche Lagerorte sind, wenn ich ihn richtig verstanden habe, nicht nötig. Wenn doch, muss man das Modell natürlich leicht anpassen.

Wenn das Material irgendwas über die Lagerung weiß, bringt man nur wieder Zyklen rein, die immer Probleme machen.
 
MaterialStock ist ja bereits ein Detail, das sich aus der Datenbank-Normalisierung ergeben hat (würde).
Zwischen Lager und Material gibt es eine n:m-Beziehung (in einem Lager lagern verschiedene Materialien und "ein Material" kann in mehreren Lägern vorrätig sein). Damit ist die Beziehung jedoch nicht vollständig beschrieben, weil noch Details wie z. B. Mengen fehlen. Zu deren Beschreibung wird die Klasse MaterialStock eingeführt. In UML nennt man eine Klasse, die eine Beziehung konkretisiert übrigens association class, sähe dann etwa so aus:

StorageLocMaterial.png

Dabei stellt {non-unique} klar, dass die Beziehung zwischen StorageLocation und Material mehrfach vorkommen kann ("ein Material" kann in einem Lager in mehreren Lagerfächern gelagert sein).

So wie ich den TE verstanden habe, möchte der Bearbeiter wissen, wo welche Materialien liegen. Dabei war es für mich logisch, dass die Suchkette damit beginnt, dass in einem Objekt Lager, dem "Root-Objekt", eine Suche nach dem Material durchgeführt wird.
Das DDD-Modell ist kein Abfragemodell und sollte auch nicht als solches verwendet werden - sofern es nicht zufällig passt.

Außerdem werden Bestände von Material nur auf Lagerort-Ebene betrachtet, nicht auf Lagerplatz-Ebene.
Wenn ich es richtig vestehe (Lagerort = StorageLocation = Lager und Lagerplatz = Lagerfach = StorageBin), dann stimmt etwas nicht:
1. entweder darf "ein Material" an verschiedenen Lagerplätzen gelagert sein, dann passt das Modell nicht zur zitierten Aussage, denn MaterialStock gibt den Bestand eines Materials je Lagerplatz an.
2. oder aber "ein Material" wird an einem Lagerort nur an einem einzigen Lagerplatz gelagert. Dann müsste im Diagramm oben {non-unique} entfernt werden.
Als dritte Alternative bliebe noch, dass die Aussage anders zu interpretieren ist.
 
An einem Lagerort (= Lager) lagern verschiedene Materialien und ein Material wird an einem Lagerort nur an einem Lagerplatz gelagert. {non-unique} muss damit entfernt werden.

@mihe7 Danke!

Lagerort = Lager und Lagerplatz = Fach sind tatsächlich leicht verwirrend. Hilft aber nichts, die Begriffe werden bei uns genau so verwendet.
 
Zuletzt bearbeitet:
Ich hätte nicht gedacht, dass sich das Domänenmodell solange hinziehen wird und hoffe, dass lässt nicht auf meine geistige Verfassung schließen 😉

Das ist der Stand:dom_material.png

Soll "MaterialBooking" im Domänenmodell überhaupt auftauchen und wie ist die Assoziation?

Jetzt habe ich ein Domänenmodell und wie geht es jetzt weiter?

Aus dem Domänenmodell werden die Aggregates, Entities und ValueObjects modelliert. Dafür gibt es ein paar Faustregeln:
  1. Fachliche Invarianten innerhalb der Aggregate-Grenzen
  2. Kleine Aggregate
  3. Referenz auf andere Aggregate nur über die Identität
  4. Aktualisierung anderer Aggregate durch "eventual consistency"
Es ist also vermutlich eine dumme Idee alles in ein Aggregat "Material" zu packen (Regel 2).

Als ersten Schuss würde ich mal sagen:
Aggregates: Material, StorageLocation
ValueObject: QuantityUnit

Bei MaterialStock bin ich mir nicht sicher. In der DB hat es sicher eine Id, aber wie und in welchen Tabellen die Daten des Modells in der DB abgebildet werden ist hier vermutlich völlig unerheblich. Ich würde MaterialStock vielleicht eher als ValueObject sehen und in einem der beiden Aggregate unterbringen.
 
Ich hätte nicht gedacht, dass sich das Domänenmodell solange hinziehen wird und hoffe, dass lässt nicht auf meine geistige Verfassung schließen 😉
Nein, nein... 🙂 Spaß bei Seite: das Problem ist einfach, dass wir alle unterschiedliche Voraussetzungen und Vorstellungen haben. @AndiE scheint z. B. fachlich im Thema zu stecken, ich dagegen habe mit Lagerverwaltung in der Form gar nichts am Hut. Außerdem waren die Begrifflichkeiten abzuklären. Dann darf man nicht vergessen, dass wir uns nicht gegenübersitzen. Hält natürlich auch auf. Außerdem ist "lange" relativ. Das kenne ich ganz anders: wenn genügend Leute meinen, beteiligt sein zu müssen, dann sind da Monate(!) teilweise nichts :-(
Lagerort = Lager und Lagerplatz = Fach sind tatsächlich leicht verwirrend. Hilft aber nichts, die Begriffe werden bei uns genau so verwendet.
Das ist kein Problem - alles nur aneinandergereihte Buchstaben. Man muss sich nur einig werden.

Jetzt muss ich nochmal rückfragen: wir wissen jetzt, dass ein Material immer nur an einem Lagerplatz liegen kann, wie sieht es umgekehrt aus? Kann an einem Lagerplatz verschiedenes Material liegen?
 
Jetzt muss ich nochmal rückfragen: wir wissen jetzt, dass ein Material immer nur an einem Lagerplatz liegen kann, wie sieht es umgekehrt aus? Kann an einem Lagerplatz verschiedenes Material liegen?

Ja, weil der Lagerplatz nur eine Art Hilfe ist um Material schneller finden zu können. Der Lagerplatz ist einfach nur ein Freitext. Er kann genauso "Schrank 5" lauten als auch "bei Meier in der Werkbank" und ist also nicht auf eine vorgegebene Menge begrenzt. Lagerorte sind vorgegeben und müssen aus einer gegebenen Menge ausgewählt werden (die natürlich auch erweitert werden kann => Stammdatenverwaltung).

Außerdem werden Bestände von Material nur auf Lagerort-Ebene betrachtet, nicht auf Lagerplatz-Ebene.

Es gibt einen (Material-) Bestand für jeden Lagerort, an dem das Material gelagert wird.
Da der Lagerplatz (storageBin) ein Feld von Bestand ist, kann es dadurch nur einen Lagerplatz pro Lagerort für einen Bestand geben.

Und damit noch mal zur obigen Frage: Es kann natürlich für unterschiedliche Materialbestände der gleiche "Schrank" angegeben werden. "storageBin" ist nur ein Feld im Bestand ohne Bezug zu irgend einer Klasse außerhalb.

Edit: Vielleicht wäre es von Anfang an besser gewesen, den Begriff "Lagerplatz" aus der Beschreibung heraus zu lassen, um Verwirrung zu vermeiden. Ich werde das Feld von "storageBin" in "storageBinInfo" umbenennen, um den Charakter deutlicher hervorzuheben.
 
Zuletzt bearbeitet:
Ich würde in dem Fall auch den Lagerplatz auch explizit modellieren 😉
Weil er eine wichtige fachliche Information darstellt und im Modell nicht untergehen darf, oder warum sonst?

Deine Aussage ist ja ungefähr entgegen gesetzt zu meiner (was keine Bewertung sein soll):
Vielleicht wäre es von Anfang an besser gewesen, den Begriff "Lagerplatz" aus der Beschreibung heraus zu lassen, um Verwirrung zu vermeiden.
 
Zuletzt bearbeitet:
Noch mal eine Nachfrage: Für mich ist ein Lager eine Einrichtung mit einem Tresen. Man gibt seine Materialanforderung rein und bekommt vom Lagerverwalter sein Material ausgehändigt. Hinter dem Tresen befindet sich der Lagerraum in dem sich viele Regale etc. befinden, worin die Dinge liegen, die man anfordern kann. In diesem Falle wären das drei Lager, die z.B. nach Stoffart unterschieden sind: Flüssigkeitslager( Farben, Farbstoffe) und Außenlager für große Dinge wie Bretter, Kisten, Tröge. Wenn von etwas etwas fehlt, wird es angefordert und vom Lagerververwalter, der hinter dem Tresen tätig ist, eingelagert.

Neben diesem (Zentral-)Lager gibt es an den Arbeitsplätzen noch (Hand-)Lager. Fehlt einem Mitarbeiter etwas, oder geht zur Neige, dann füllt er den Bestand aus dem Lager auf.

@temi: Ich glaube, du meinst das nicht so, wie ich das geschildert habe, nicht?
 
Ich glaube, du meinst das nicht so, wie ich das geschildert habe, nicht?
Also einen Tresen muss es nicht unbedingt geben und auch keinen Lageristen 😉.
Wer einen Artikel entnimmt oder einlagert ist auch nicht relevant bzw. kann ggf. über Berechtigungen beschränkt werden.

Für diese Domäne ist ein Lagerort nur ein "Ding" auf dem bezogen ein Materialbestand verwaltet werden kann.

Ein realer Lagerort kann ein Gebäude sein, ein Raum oder ein Schrank/Regal, je nachdem wie man es definiert. Entscheidend ist nur das Bestände bezogen auf einen Lagerort verwaltet werden können.

In dieser Domäne ist der Lagerort die einzige Ebene auf der Bestände verwaltet werden können.

Denkbar wären als übergeordnete Ebene das "Werk" = Werksbestand und als darunter liegende Ebene der "Lagerplatz" = Lagerplatzbestand. Beides ist hier nicht gefordert.
 
Zuletzt bearbeitet:
Weil er eine wichtige fachliche Information darstellt und im Modell nicht untergehen darf, oder warum sonst?

Deine Aussage ist ja ungefähr entgegen gesetzt zu meiner (was keine Bewertung sein soll):
Ja, ist schließlich ein vorkommendes Konzept, da wäre es besser als wirkliche Klasse, als nur als Attribut aufgehoben 😉

Die Verwirrung kam ja in dem Fall zT durch fehlendes Verständniss, da hätte das mMn schon geholfen.
 
Zuletzt bearbeitet:
Ich bin jetzt schon beim nächsten Schritt, dem Bildung der Aggregate. Ich möchte nun wissen, wie es zu einer Bestellung kommt. Wenn es keinen Lagerverwalter gibt, wäre auch das System denkbar, wie man es zu Hause macht.

Monteur benötigt Material->(Monteur sieht)Das Material geht zur Neige->(PC)Ist noch was vorhanden?->JA->Lagerort suchen->(benötigtes Material umlagern)->Material neubestellen->(Auf Lieferung warten)->Material einbuchen

An Stelle PC würde man die Lagerverwaltung anwerfen und damit arbeiten.

Im Prinzip ist dann hier die Größe des Bestandes egal. Da reicht auch eine Ampel: grün- genügend; gelb-wird eng; rot nur noch einige Reste.
 
Dazu brauche ich das OK des Fachexperten. Erst dann kann ich die "Domain Events" festlegen und dazwischen die Aggregate anlegen.
 
Dazu brauche ich das OK des Fachexperten. Erst dann kann ich die "Domain Events" festlegen und dazwischen die Aggregate anlegen.
Bestellungen werden von der Teildomäne "Materiallager" nicht abgedeckt. Hatte ich auch ein paar Beiträge weiter oben schon mal geschrieben. Damit das hier nicht zu groß wird sollten wir uns darauf beschränken. Meine Meinung.
 
1. check empty items->EmptyItemsChecked
2. check storage location->StorageLocationChecked
3. Move Items-> Items Moved
4. Require Items->Items Required

Vorbehaltlich, dass ich jetzt völlig falsch liege.
Im ersten Aggregat werden alle leeren Fächer gesammelt und zu einer Liste/Tabelle zusammengefügt.

Im zweiten Aggregat wird kontrolliert, ob diese Dinge noch irgendwo vorhanden sind. Es werden zwei Tabellen erstellt: Eine mit Dingen die doppelt vorhanden sind und eine mit denen, die nicht mehr weiter vorhanden sind.

Im dritten Aggregat wird eine Liste erzeugt, wo noch Dinge zu finden sind. Werden sie bewegt, verändert sich ja ihr Lagerort.

Im vierten Aggregat wird eine Liste erstellt, was neu zu besorgen ist. Hier ist dann die Schnittstelle zum Bestellwesen.
 
Soll "MaterialBooking" im Domänenmodell überhaupt auftauchen und wie ist die Assoziation?
Die Domäne dürfte "Lagerverwaltung" sein - von daher ja. Die Buchung gibt an, in welchem Lager bezogen auf welches Material ein Zu- oder Abgang erfolgte (zzgl. ggf. weiterer Details, wer, wann, ...)

Das Lager "führt die Buchung durch", indem es den betreffenden Bestand verwaltet. Würde m. E. zumindest aktuell sinnvoll erscheinen. Schauen wir mal.

Aggregate (aggregate roots fett):
1. StorageLocation und MaterialStock
2. Material
3. MaterialBooking

MaterialStock hat über das Material eine lokale Identität innerhalb der StorageLocation. Material weiß nichts vom Rest. Die Buchung gibt eine Referenz auf die StorageLocation und das Material an. D. h. anhand der Buchung kann die StorageLocation ermittelt werden. Dieser kann die Buchung zur "Durchführung" übergeben werden. Die StorageLocation kann anhand der in der Buchung angegebenen Referenz zum Material den Lagerplatz ermitteln, Geschäftsregeln durchsetzen usw. Hört sich zumindest für mich im ersten Moment nicht schlecht an.
 
Aggregate (aggregate roots fett):
1. StorageLocation und MaterialStock
2. Material
3. MaterialBooking

  • MaterialStock hat über das Material eine lokale Identität innerhalb der StorageLocation.
  • Material weiß nichts vom Rest.
  • Die Buchung gibt eine Referenz auf die StorageLocation und das Material an. D. h. anhand der Buchung kann die StorageLocation ermittelt werden. Dieser kann die Buchung zur "Durchführung" übergeben werden.
  • Die StorageLocation kann anhand der in der Buchung angegebenen Referenz zum Material den Lagerplatz ermitteln, Geschäftsregeln durchsetzen usw. Hört sich zumindest für mich im ersten Moment nicht schlecht an.

Gibt es eine Fausregel, wie man hier generell vorgeht?

StorageLocation und Material haben eine natürliche Identität durch die StorageLocationId und die MaterialId. Beide Identitäten sind für den User zur Verwendung der Lagerverwaltung notwendig (z.B. Beschriften der Fächer mit der Materialnummer).

Was bestimmt denn die Identität von MaterialBooking? Die Referenzen auf Material und StorageLocation einzeln oder zusammen können es nicht sein, weil es mehrere Buchungen für das selbe Material im selben Lager geben kann.
Ich hätte MaterialBooking eher als ValueObject gesehen, weil es eigentlich nicht mehr darstellt, als eine Zusammenstellung von Fachwerten. Ähnlich ist es bei MaterialStock (wobei es hier die "lokale Identität" durch die MaterialId innerhalb einer StorageLocation gibt). Müssen dafür jetzt künstliche Identitäten geschaffen werden?

QuantityUnit ist ein ValueObject und gehört zu Material. Hier gibt es u.U. ein kleines Problem, weil die QuantityUnit für das Material festgelegt wird, aber auch für die Berechnung der Bestände an anderer Stelle benötigt wird. Designfehler?

StorageBin ist ein ValueObject und gehört zu MaterialStock.
 
Antwort kommt später, hab gerade keine Zeit.
Kein Ding.
Geschäftsregel ist z. B. dass Material an einem Lagerort nur an einem Lagerplatz liegen darf.
Es geht mehr darum, ob die Geschäftsregeln irgendwie im Domänenmodell dokumentiert werden, z.B. eine Liste irgendwo am Rand. Sprich: Sollte das Domänenmodell so vollständig sein, dass sich alle Geschäftsregeln und was es sonst noch so gibt daraus lesen lassen?
 
Aggregate (aggregate roots fett):
1. StorageLocation und MaterialStock
2. Material
3. MaterialBooking

Wie bekommt man dem nun Leben eingehaucht? Dazu würde ich gerne wissen, wie das System angewendet werden soll. Momentan würde ich das so sehen:

START->Bearbeiter sucht nach einem Material-> 1. Ist das Material im System vorhanden?-JA->Bearbeiter sucht nach Ort, wo er das Material finden kann->2. Will der Mitarbeiter Material entnehmen?->JA->3. Ist das Material noch ausreichend vorhanden?->JA->ENDE

1. NEIN->Material neu in Bestand aufnehmen
2. NEIN->Material datentechnisch in Bestand einfügen. Physisch an Stelle ablegen.
3. NEIN->Auf Wunschliste schreiben.

Könnte man das so nehmen?
 
Wie bekommt man dem nun Leben eingehaucht?
Indem man eine Anwendung drum rum baut, nur das Modell hat natürlich erstmal kein "Leben".
Aber alles, was du für deinen Use-Case unten brauchst, ist im Modell vorhanden.

Dazu würde ich gerne wissen, wie das System angewendet werden soll. Momentan würde ich das so sehen:

START->Bearbeiter sucht nach einem Material-> 1. Ist das Material im System vorhanden?-JA->Bearbeiter sucht nach Ort, wo er das Material finden kann->2. Will der Mitarbeiter Material entnehmen?->JA->3. Ist das Material noch ausreichend vorhanden?->JA->ENDE

1. NEIN->Material neu in Bestand aufnehmen
2. NEIN->Material datentechnisch in Bestand einfügen. Physisch an Stelle ablegen.
3. NEIN->Auf Wunschliste schreiben.

Könnte man das so nehmen?
Das klingt zumindest nicht gänzlich falsch...
 
Sollte das Domänenmodell so vollständig sein, dass sich alle Geschäftsregeln und was es sonst noch so gibt daraus lesen lassen?

Das kommt jetzt darauf an, was wir unter Domänenmodell verstehen wollen. Das Domain Model als Teil der Software muss die Geschäftsregeln natürlich irgendwie abbilden. Bei den Diagrammen zum Domain Model finde ich, wäre es übertrieben, wenn wirklich jeder "Mist" dargestellt werden würde.

Ich würde auch z. B. keine explizite MaterialStockAmountMustNotBeNegative-Rule einführen 🙂 Dass ein Bestand nicht negativ werden kann, ist invariant und wird sich auch künftig nicht ändern.

1. Ist das Material im System vorhanden?
Das DDD-Modell ist oft zu komplex, um es als Query-Model gebrauchen zu können. Diese Info würde man aber ggf. sogar noch direkt über das Material-Repository bekommen.

Material neu in Bestand aufnehmen
Material-Repository

Material datentechnisch in Bestand einfügen.
Bestand einbuchen.

Auf Wunschliste schreiben.
Post-it 😉
 
Das kommt jetzt darauf an, was wir unter Domänenmodell verstehen wollen. Das Domain Model als Teil der Software muss die Geschäftsregeln natürlich irgendwie abbilden. Bei den Diagrammen zum Domain Model finde ich, wäre es übertrieben, wenn wirklich jeder "Mist" dargestellt werden würde.

Ich würde auch z. B. keine explizite MaterialStockAmountMustNotBeNegative-Rule einführen 🙂 Dass ein Bestand nicht negativ werden kann, ist invariant und wird sich auch künftig nicht ändern.
Wobei es oftmals praktisch ist, relevante Dinge irgendwie als Notiz dranzuhängen, sollte natürlich nicht zu viel werden.

Sowas wie "MaterialStockAmountMustNotBeNegative" würde ich einfach über einen nicht-negativen Datentypen abbilden 😛
 
Ein kleines Statement zu meinen Fragen in https://www.java-forum.org/thema/fragen-zur-software-architektur.182299/page-9#post-1160344 wäre noch nett, wenn es eure Zeit erlaubt. 🙂

Möglicherweise werden sich viele noch offene Fragen auch (fast) von selbst lösen; das Buch "DDD kompakt" wurde hier bereits erwähnt. Meiner Meinung nach ist das Buch ziemlich überflüssig, weil es zu viele Fragen offen lässt, bzw. ständig auf das Buch "Implementing DDD" von Vernon verweist. Genau dieses Buch habe ich mir jetzt zugelegt und auf den ersten Blick wird hier deutlich detaillierter und mit vielen Beispielen auf das Thema eingegangen. Mehr werde ich allerdings erst wissen, wenn ich mit dem Lesen fertig bin.

Gruß,
temi
 
Im Buch hilft Kapitel 5 schon etwas, wie man Entitys entwickelt. Ich würde aber auch ohne Buch nun weitergehen und eine erste Implementierung versuchen. Dabei finde ich es wichtig, sich auf das Wesentliche zu konzentrieren. Die solltest dir ziemlich einfach einen Lagerbestand aufbauen. In etwa so:

Java:
...
List ml= new List<Material>();
Material m1=  new Material(1,"Stahl","m");
//ID, name, messure
ml.add(m1);
// Das ganze ein paar Mal

List sl= new List<StorageLocation>();
StorageLocation st=new StorageLocation(1,"Keller");
//id, description
sl.add(st);

usw.

Der Sinn dahinter ist, dass du dir aufgrund deines Modells ein Dummy-Lager aufbaust. Nun fehlt noch die m:n-Beziehung mit der Beziehungsklasse, mit der du dein Lager füllst.

Dann kannst du im nächsten Schritt mal die Anwendung durchspielen.
 
Ich würde aber auch ohne Buch nun weitergehen und eine erste Implementierung versuchen.
Um die Implementierung geht es mir hier eigentlich gar nicht so sehr, sondern nur um die Architektur des Systems und da hab ich schon noch einige Fragen, die mir unter den Nägeln brennen. Es soll in diesem Thema auch keine vollständige Anwendung rausfallen, es geht mir um den Weg dahin und vielleicht ein paar "best practices" (ganz am Schluss soll natürlich eine funktionierende Anwendung stehen, aber die muss ich hier nicht komplett diskutieren). Wir können das aber gerne später unter uns diskutieren, wenn es dich interessiert.
 

Zurück
Oben