Fragen zur Software-Architektur

temi

Top Contributor
"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?
 

mihe7

Top Contributor
Evtl. habe ich falsch übersetzt/interpretiert. Kannst Du (ggf. nochmal?) kurz schreiben, was StorageLocation und MaterialStock sein soll?
 

temi

Top Contributor
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?
 

mihe7

Top Contributor
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.
 

temi

Top Contributor
Zuletzt bearbeitet von einem Moderator:

mrBrown

Super-Moderator
Mitarbeiter
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:

temi

Top Contributor
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 :)
 

mrBrown

Super-Moderator
Mitarbeiter

temi

Top Contributor
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.
 

mrBrown

Super-Moderator
Mitarbeiter
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.
 

temi

Top Contributor
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:

temi

Top Contributor
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.

:):):):):):):):):):):):):):):):)
 

mrBrown

Super-Moderator
Mitarbeiter
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 ;)
 

temi

Top Contributor
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:

AndiE

Top Contributor
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.
 

temi

Top Contributor
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:

temi

Top Contributor
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?
 

AndiE

Top Contributor
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.
 

mrBrown

Super-Moderator
Mitarbeiter
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.
 

mihe7

Top Contributor
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.
 

temi

Top Contributor
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:

temi

Top Contributor
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.
 

mihe7

Top Contributor
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?
 

temi

Top Contributor
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:

temi

Top Contributor
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:

AndiE

Top Contributor
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?
 

temi

Top Contributor
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:

mrBrown

Super-Moderator
Mitarbeiter
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:

AndiE

Top Contributor
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.
 

AndiE

Top Contributor
Dazu brauche ich das OK des Fachexperten. Erst dann kann ich die "Domain Events" festlegen und dazwischen die Aggregate anlegen.
 

temi

Top Contributor
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.
 

AndiE

Top Contributor
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.
 

mihe7

Top Contributor
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.
 

temi

Top Contributor
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.
 

mihe7

Top Contributor
@temi Antwort kommt später, hab gerade keine Zeit. Geschäftsregel ist z. B. dass Material an einem Lagerort nur an einem Lagerplatz liegen darf.

@AndiE was meinst Du?
 

temi

Top Contributor
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?
 

AndiE

Top Contributor
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?
 

mrBrown

Super-Moderator
Mitarbeiter
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...
 

mihe7

Top Contributor
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 ;)
 

mrBrown

Super-Moderator
Mitarbeiter
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 :p
 

temi

Top Contributor
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
 

AndiE

Top Contributor
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.
 

temi

Top Contributor
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.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
F Paket und Software Design Fragen. Allgemeine Java-Themen 5
Zrebna Fragen zu Testabdeckungs-Metriken Allgemeine Java-Themen 4
MarvinsDepression Unbekanntes Zeichen in fremden Code wirft Fragen auf Allgemeine Java-Themen 4
B HTTP Allgemeine Fragen über Suchmaschine nutzen mit Java Allgemeine Java-Themen 20
K BlueJ - Fragen zu dem Spiel Pacman (Nachprogrammieren) Allgemeine Java-Themen 141
V Ich hätte 2 Fragen Allgemeine Java-Themen 5
ME2002 Fragen aus einer Java Klausur Allgemeine Java-Themen 67
H Fragen zur Kraken Api Allgemeine Java-Themen 1
nonickatall Klassen Grundsätzliche Fragen zu geplanter Programmstruktur Allgemeine Java-Themen 5
W Ein paar Fragen zu .properties und .css Allgemeine Java-Themen 6
W Mal ein paar generelle Fragen zu InputStream und OutputStream Allgemeine Java-Themen 4
X Fragen zur Javamail API und Gmail Allgemeine Java-Themen 4
T Fragen bezgl. Lambdas Allgemeine Java-Themen 20
X Collections Fragen zu gleichen Elementen in TreeSet Allgemeine Java-Themen 35
A Neuerungen in Java 8 StreamAPI- Paar fragen Allgemeine Java-Themen 4
M Diverse Design-Fragen Allgemeine Java-Themen 6
J 2 Fragen zur Vererbung Allgemeine Java-Themen 5
H Java FX 2 Fragen um Programm in mehrere sprachen zu übersetzen in Gluon Framwork Allgemeine Java-Themen 3
M Fragen beantworten über Textfeldeingabe Allgemeine Java-Themen 5
D Grundsätzliche Fragen zum Heap Space Allgemeine Java-Themen 12
J Allgemeine Fragen zu Vererbung Allgemeine Java-Themen 1
M Allgemeine Fragen meinerseits Allgemeine Java-Themen 4
V Wie kann ich die Fragen mit den anderen Klassen verbinden? Allgemeine Java-Themen 1
J Fragen zu generischer doppelt verketteter Liste (bei fehlendem Grundverständnis) Allgemeine Java-Themen 1
R Es gibt keine dummen Fragen (hab ich mal gehört) Allgemeine Java-Themen 11
T Fragen zum Thread-Thema Allgemeine Java-Themen 4
2 2 Klein Fragen Allgemeine Java-Themen 7
alderwaran .jar Code Signing, User-Keystore und Fragen dazu Allgemeine Java-Themen 0
T Fragen zum Thread-Thema Allgemeine Java-Themen 9
A Java Theorie-Fragen Allgemeine Java-Themen 7
K Java QUIZ-Spiel Fragen und Antworten generieren?! Allgemeine Java-Themen 5
R Socket Fragen zu UDP Allgemeine Java-Themen 1
B Noob-Fragen zu Tablets und PC kompatiblität... Allgemeine Java-Themen 6
D Ein paar allgemeine Fragen zu Java Allgemeine Java-Themen 19
L Fragen für Facharbeit: Analyse von Strings in Java Allgemeine Java-Themen 4
R Fragen zu Server + UI Allgemeine Java-Themen 2
U Vier Fragen zu Java Allgemeine Java-Themen 2
H MediaManager Fragen/Probleme Allgemeine Java-Themen 6
D Fragen zum erstellen einer ausführbaren Jar Datei Allgemeine Java-Themen 3
C Polymorphie Fragen zur Annotations von Persistenz Allgemeine Java-Themen 2
O Fragen über Fragen - Bei Änderung XML-Datei -> Anpassung GUI Allgemeine Java-Themen 7
StrikeTom Java Performance Fragen Allgemeine Java-Themen 5
Luk10 Fragen zum ByteBuffer (lwjgl - icons) Allgemeine Java-Themen 2
F Akkumulator Hough-Transformation offene Fragen Allgemeine Java-Themen 4
Luk10 Fragen zu Naming-Conventions Allgemeine Java-Themen 5
Z Einige Fragen Allgemeine Java-Themen 10
T OOP Einige Fragen zu UML-Klassendiagrammen Allgemeine Java-Themen 6
G Einige Fragen zu ResourceBundles Allgemeine Java-Themen 2
S Fragen zu verschiedenen Themen vom JCreator Allgemeine Java-Themen 2
DStrohma Grundsätzliche Fragen zum Aufbau eines komplexeren Programmes Allgemeine Java-Themen 8
Semox Grapheneditor - Allgemeine Fragen zum Logikdesign Allgemeine Java-Themen 3
O kleine Fragen eines Anfängers Allgemeine Java-Themen 2
X Executor fragen ob fertig Allgemeine Java-Themen 13
nrg Swing 2 Fragen zu Swing/AWT Allgemeine Java-Themen 7
K Reflections Fragen Allgemeine Java-Themen 7
S Fragen zum SCJD-Zertifikat Allgemeine Java-Themen 2
M Backend Entwicklung - Konzept fragen Allgemeine Java-Themen 3
E Fragen zu Scala Allgemeine Java-Themen 11
Daniel_L Fragen zu RegEx und URL umwandeln Allgemeine Java-Themen 4
J Diverse Fragen bezüglich Jasper Allgemeine Java-Themen 3
S Fragen zum ShutdownHook Allgemeine Java-Themen 7
V Fragen zu einem Java Browser Allgemeine Java-Themen 7
G Fragen zum eigenen Scheduler Allgemeine Java-Themen 4
M Drag and Drop: 3 Fragen Allgemeine Java-Themen 3
L Einige Fragen zu Java Allgemeine Java-Themen 9
F Linguistische Fragen zu Javadoc bzw. Englisch Allgemeine Java-Themen 4
E Einfache Fragen zu Dateien Allgemeine Java-Themen 7
E Thread Fragen in Verbindung mit Swing Allgemeine Java-Themen 4
M MVC Design Pattern - Verständniss Fragen Allgemeine Java-Themen 3
X Einige Fragen zu Serialisierung Allgemeine Java-Themen 2
H Java Multiplicoice Test (10 Fragen) Allgemeine Java-Themen 11
J Viele Fragen. =) Hoffentlich könnt ihr helfen Allgemeine Java-Themen 9
D Grundsätzliche Fragen zur Grafikdarstellung in Spielen Allgemeine Java-Themen 2
J 2 Fragen zu JMF und eine Rechtsfrage Allgemeine Java-Themen 3
S Viele Fragen eines Umsteigers (von .NET) Allgemeine Java-Themen 6
C LinkedList Fragen Allgemeine Java-Themen 7
P Fragen zur JBuilder und den kosten. Allgemeine Java-Themen 7
reibi JVM fragen welche Apps geladen sind Allgemeine Java-Themen 7
I Fragen zum Internetseiten Einlesen/Auswerten Allgemeine Java-Themen 5
S 2 Fragen allgemeine fragen zu final und interface Allgemeine Java-Themen 13
M ein paar fragen über JBoss und Catalina Allgemeine Java-Themen 7
D Allgemeine Fragen zum Speichern Allgemeine Java-Themen 3
F allgemeine Fragen zu Java Allgemeine Java-Themen 9
S Fragen zu 4 speziellen Listen Allgemeine Java-Themen 4
U JFrame, JOptionPane - vor dem Schließen Benutzer fragen Allgemeine Java-Themen 10
I zwei simple fragen Allgemeine Java-Themen 22
G 2 Fragen Allgemeine Java-Themen 7
G Fragen zu ausführbaren JAR Files Allgemeine Java-Themen 23
G Fragen zu JTextField bzw. JTextArea Allgemeine Java-Themen 2
J 5 Fragen. Allgemeine Java-Themen 2
P Tausend Fragen... Allgemeine Java-Themen 3
Zrebna Zuverlässiges Automatisiertes Testen im eigenem Software-Unternehmen aufsetzen - How to? Allgemeine Java-Themen 12
I In Java geschriebene Software nach Mac OS portieren Allgemeine Java-Themen 7
OnDemand Software Zertifizierung Allgemeine Java-Themen 4
Zrebna Wieviele Testfälle muss man hier schreiben? (Software Engineering) Allgemeine Java-Themen 13
Kirby.exe Software Entwicklung Allgemeine Java-Themen 9
Kirby.exe Software für Graphische Visualisierung Allgemeine Java-Themen 20
B Multiuser Software Allgemeine Java-Themen 3
L Nach dem Login // Java Desktop Software Allgemeine Java-Themen 7
W Software-Lizenzen Allgemeine Java-Themen 13

Ähnliche Java Themen


Oben