User Tools

Site Tools


applications:prom:projectstructure

This is an old revision of the document!


Die Projektstruktur in PRO•M

Die Projektstruktur in PRO•M ist hierarchisch: Wenn wir DDD1) anwenden, müssen wir innerhalb dieser Struktur Aggregates identifizieren und definieren. In der Delphi 6.0 Entwicklung war das einzelne Projekt das Aggregate, und für bestimmte Änderungen wurde UOW2) verwendet, indem mehrere Projekte gemeinsam in eine Transaktion behandelt wurden. Wird z.B. Projekt 1.1.2 von Projekt 1.1 entfernt und unter Projekt 1.2 gehängt, werden alle 3 Projekte gesperrt. Es wird dann geprüft, ob Projekt 1.1.2 kein Vorfahr von Projekt 1.2 ist, weil es ansonsten einen Zirkel gibt3).

Es wird aber auch geprüft, ob Projekt 1.2 noch keine Vorgänge unter sich hängen hat. Dafür werden dann die Projekte 1.2.1. und 1.2.2 auch noch gesperrt4).

Wenn also Projekt 1.1.2 unter Projekt 1.2 gehängt wird, werden folgende Projekte gesperrt: Das bedingt eine Transaktion, bzw. ein UOW5). Dafür müssen alle Projekt auch in einem Dataspace leben, ansonsten müsste man eine verteilte Transaktion für den UOW verwenden, etwas das spätestens seit Pat Hellands Artikel vermieden werden sollte.

Identifizieren von Aggregates für die Projektstruktur

Das System/Der Mandant als Aggregate Root

Das System könnte für die Projektstruktur verantwortlich sein: Vorteile:

  • Zirkelbezüge können strikt vermieden werden
  • Das Read Model ist immer konsistent

Hierbei handelt es sich aber um ein globales Aggregate mit allen bekannten Nachteilen:

  • Bei tausenden von Projekten müsste das gesamte Aggregate geladen werden wenn ein neues dazu kommt oder die vorhandene Struktur verändert wird - kostspielig,
  • Bei Hunderten von Anwendern, die allesamt auf die Projektstruktur zugreifen möchten, besteht ein großes Konfliktpotenzial. Das kann zwar aufgelöst werden, indem man bei einem Zugriffskonflikt6) die Aktion ein weiteres mal sendet. Eine saubere Trennung wäre das trotzdem nicht, sondern nur eine nachgelagerte Lösung eines Problems, das durch die schlechte Wahl der Aggregates entstanden ist.

Das Hauptprojekt als Aggregate Root

Man könnte das Hauptprojekt, bzw. den Projektstrukturplan7) als Aggregate Root verwenden: So können alle Regeln sicher gestellt werden, u.a.

  • keine Zirkelbezüge
  • keine Vermischung von Projekten und Projektvorgängen auf einer Ebene
  • Statuskombinationen von Projekt zu Teilprojekt
  • und vieles mehr

Es gibt trotzdem noch Problemen mit dieser Struktur, ähnlich wie bei einem globalen Aggregate:

  • Immer noch ein Konfliktpotenzial, weil der Zugriff auf alle Teilelemente immer über das Hauptprojekt läuft. Angenommen ein Organisationsleiter legt ein Hauptprojekt an und darunter 3 Teilprojekte, die er alle an Teilprojektleiter delegiert. Die drei Teilprojektleiter sollten nun unabhängig von einander an ihren Teilprojekten arbeiten können, ohne sich in die Quere zu kommen. Das ist in dieser Struktur nicht möglich, bzw. nur mit hohen Kosten verbunden. Wenn z.B. ein Teil-Teilprojektleiter an Projekt 1.2.2 arbeitet8), müsste immer die Gesamte Struktur geladen werden. Und wenn ein anderer an Projekt 1.2.1 arbeitet, müssten die Änderungen bei Konflikten eventuell mehrmals gesendet werden, damit sie gespeichert werden können.
  • Es gibt keine Möglichkeit aus einem Teilprojekt9) ein Hauptprojekt10) zu machen - Man kann keine Entitäten aus Aggregates ziehen um daraus eigene Aggregates zu machen.
  • Es gibt keine Möglichkeit aus einem Hauptprojekt ein Teilprojekt zu machen11).

Ein Problem ist, dass die Projektstruktur Projekte enthält. Im Grunde müsste die Projektstruktur Referenzen auf Projekt enthalten, wobei jedes Projekt ein eigenes Aggregate ist:

Projektstruktur als Aggregate Root

Das sieht ja schon gewaltig aus. Ist aber im Grunde recht einfach. Ein Projekt ist ein eigenständiges Aggregate, und kann auch als solches existieren. Über die Projektstrukturpläne wird es in eine Struktur eingefügt.

Innerhalb einer Projektstruktur können Regeln bezüglich der Zirkelbezüge und dem Vermischen von Projekten und Projektvorgängen geprüft und eingehalten werden. Das Arbeiten am Projekt ist unabhängig vom Arbeiten an der Struktur, was schon ein großer Schritt in die richtige Richtung ist.

Was noch nicht geht ist, dass die Teilprojektleiter unabhängig von einander die Strukturen bestimmen können. Ein weiters Problem entsteht, wenn man z.B. die Referenz auf Projekt 1.2 aus der Projektstruktur 1 in die Projektstruktur 2 unter die Referenz auf Projekt 2 hängen möchte. Man müsste alle Referenzen unter der Referenz auf Projekt 1.2 ebenfalls mit rüber nehmen, also die Referenzen auf die Projekte 1.2.1 und 1.2.2. Es gäbe also 6 Schritte:

  1. Löse die Referenz von Projekt 1.2.1 auf die Referenze auf Projekt 1.2 in der Struktur 1 auf
  2. Löse die Referenz von Projekt 1.2.2 auf die Referenze auf Projekt 1.2 in der Struktur 1 auf
  3. Löse die Referenz von Projekt 1.2 auf die Referenz auf Projekt 1 in der Struktur 1 auf
  4. Erstelle eine neue Referenz unter der Referenz auf Projekt 2 in der Struktur 2 auf Projekt 1.2
  5. Erstelle eine neue Referenz unter der Referenz auf Projekt 1.2 in der Struktur 2 auf Projekt 1.2.1
  6. Erstelle eine neue Referenz unter der Referenz auf Projekt 1.2 in der Struktur 2 auf Projekt 1.2.2

Es sind 6 Schritte, die 2 Aggregates betreffen. Die Reihenfolge muss eingehalten werden, weil die Struktur nach jedem Schritt konsistent sein muss. Man könnte die Schritte 1 bis 3 und 4 bis 6 verschmelzen. Es bleiben aber immer auf jeden Fall 2 Schritte.

Das bedeutet auch, dass die globale Sicht nicht immer zwingend konsistent sein muss. Wenn man das Ergebnis der Schritte 4 bis 6 vor dem Ergebnis der Schritte 1 bis 3 sieht12), würde man Projekt 1.2 mit den Teilprojekten 1.2.1 und 1.2.2 in beiden Projektstrukturen sehen. Das wäre nur vorübergehend, und man würde Mechanismen einbauen, um die Mengen-basierte Regel schließlich konsistent einzuhalten13).

Genauso wichtig, wenn nicht wichtiger, ist es aber, dass die Komponenten, die das Lesemodell

1) Domain Driven Design
2) , 5) Unit of Work
3) Wenn Projekt 1.1.2 ein Vorfahr von Projekt 1.2 ist, und dann Projekt 1.2 zum Vorfahr von Projekt 1.1.2 gemacht wird, haben wir einen Zirkelbezug
4) Und das ist auch gar nicht 100% sicher, weil jemand anderes parallel einen Vorgang unter Projekt 1.2 hängen könnte
6) gleichzeitiger Zugriff
7) der dann im Grunde vom Hauptprojekt identifiziert wird
8) Änderungen vornimmt
9) Entität
10) Aggregate Root
11) Die Möglichkeit gibt es schon, indem man eine Verteilte Transaktion startet, ein neues Teilprojekt anlegt, alles aus dem Hauptprojekt kopiert, und dann das Hauptprojekt löscht. Alles kopieren kann aber viele abhängige Daten bedeuten, auch bereits erfasste und fakturierte Zeitdaten. Also keine Aktion, die man in dieser Struktur ohne weiteres anbieten sollte
12) Auch wenn alles in einer UoW passiert, betreffen die Schritte 2 unterschiedliche Aggregates, und die Reihenfolge in der diese beobachtet werden, ist nicht immer sicher gestellt
13) z.B. eine UoW, oder kompensierende Aktionen
applications/prom/projectstructure.1361800564.txt.gz · Last modified: 2013/02/25 14:56 by rtavassoli