In meinem aktuellen Projekt haben wir ein sehr detailliertes Analysemodell. Detailliert beschreibt es eigentlich gar nicht. Das Modell beschreibt über 200 Klassen. Eines der vielen Probleme bei einem so umfangreichen Analysemodell ist, dass den Entwicklern kein Spielraum bleibt, um das Geschäftsmodell zu interpretieren und das technische Design zu finden, das am besten dazu passt. Die Implementierung der Klassen, die das Analysemodell mit ihren Eigenschaften und Assoziationen beschreibt, ist schon kompliziert genug, und dann müssen auch noch die Operationen und Dienste, die auf diesen Klassen basieren, entworfen und implementiert werden. Das führt dazu, dass die Entwickler die Klassen einfach so abtippen, wie das Analysemodell sie beschreibt. Ein auffälliges Beispiel ist der Fall, dass eine Many-to-Many-Assoziation Attribute erwirbt. Sehen wir uns ein Beispiel an.
Zu einem bestimmten Zeitpunkt während der Entwicklung beschreibt das Analysemodell die Klassen Game und GameSet:
Diese Analyseklassen sind genau das, wofür Sie sie halten. Ein Game ist ein Spiel mit Namen, Beschreibung und allen anderen Eigenschaften, die das Unternehmen benötigt. Ein GameSet ist eine Sammlung von Spielen, aber mit zusätzlichen Eigenschaften und Assoziationen, so dass es mit Fug und Recht eine 'echte' Analyseklasse sein kann. Wie implementieren wir das nun? Wahrscheinlich so:
Und diese zusätzliche Klasse hat einige Eigenschaften, die einige Attribute des Spiels in diesem speziellen GameSet beschreiben. Wie implementieren wir das? Ein Entwickler, der ahnungslos dem Analysemodell folgt, könnte auf diese Idee kommen:
public class Game {}
public class GameSet {
öffentliche Sammelspiele;
...
}
Das scheint gut zu funktionieren. Ein Game ist wahrscheinlich nicht so sehr daran interessiert zu wissen, an welchen GameSets es beteiligt ist, also lassen wir die Assoziation auf einer Seite abgebildet (obwohl wir der Klasse Game auch eine Sammlung von GameSets hinzufügen könnten). Wir können nun ganz einfach feststellen, welches GameSet welche Spiele enthält und wie ähnlich sich zwei GameSets sind, indem wir ihre Spiele vergleichen:
public int overlap (GameSet other) {
Sammlung overlap = this.games;
overlap.retainAll(other.games);
return overlap.size();
}
Dann, eines sonnigen Tages, beschließt jemand aus dem Analyseteam, dass er dieser Assoziation zusätzliche Attribute hinzufügen muss. Nicht alle Spiele in einem GameSet sind gleich und in jedem GameSet kann sich ein Spiel anders verhalten. Also beschließen sie, diese einfache Assoziation aufzubrechen und durch eine neue Klasse GameEnjoyment zu ersetzen (ich habe sie gefragt, und niemand weiß, woher dieser Name stammt...)
public class Game {}
public class GameEnjoyment {
öffentliches Spiel Spiel;
}
public class GameSet {
public Sammlung gameEnjoyments;
...
}
Das sieht wirklich ungeschickt aus. Ein GameSet (eine Sammlung von Spielen) hat keinen Bezug mehr zur Klasse Game. Um herauszufinden, welche Spiele im GameSet enthalten sind, müssen Sie über die GameEnjoyments iterieren und die Spiele sammeln, denen diese zugeordnet sind. Außerdem kann ein GameSet gemäß der Definition eines GameSet nur ein GameEnjoyment für ein bestimmtes Spiel enthalten. Eine weitaus bessere Implementierung würde wie folgt aussehen:
public class Game {}
public class GameEnjoyment {}
public class GameSet {
private Map gameToGameEnjoyment;
public Sammlung getGames () {
return gameToGameEnjoyment.keySet();
}
public Sammlung getGameEnjoyments () {
return gameToGameEnjoyment.values();
}
public int overlap (GameSet other) {
Sammlung overlap = this.getGames();
overlap.retainAll(other.getGames());
return overlap.size();
}
}
Diese Implementierung deckt die Bedeutung der Analyseklassen viel besser ab, auch wenn sie sich nicht buchstabengetreu an sie hält. Außerdem entfällt die Notwendigkeit, die Sammlung von GameEnjoyments immer wieder zu durchlaufen, um die zugehörigen Spiele eines GameSets zu finden.
Ich halte es für sehr wichtig, ein Analysemodell gründlich zu prüfen, bevor Sie sich für das beste technische Design entscheiden, mit dem es umgesetzt wird. Vor allem, weil sie unterschiedliche Ziele haben: Ein Analysemodell ist ein Werkzeug für die Kommunikation mit dem Unternehmen. Ein technischer Entwurf beschreibt eine API, mit der die Entwickler arbeiten können. So habe ich bei meinem aktuellen Projekt immer noch ein riesiges Analysemodell, bei dem jede kleine Änderung der geschäftlichen Anforderungen Dutzende von Klassen und die dazugehörigen Dienste nach sich zieht. Ich denke, das Hauptproblem dabei ist, dass das Analysemodell weder ein Kommunikationswerkzeug ist (niemand versteht wirklich, wofür all diese Klassen und Eigenschaften da sind, außer vielleicht der leitende Architekt, der übrigens nächstes Jahr in den Ruhestand geht), noch beschreibt es eine brauchbare API für die Programmierer, denn sie müssen sich durch ein Diagramm nach dem anderen wühlen, um herauszufinden, wie das GameSet mit den Games (vergessen Sie nicht die GameEnjoyments) schließlich zu GameParticipations führt, die mit PaymentObligations zusammenhängen, die eine Subscription bilden, die eine Relation hat. Ich denke, dass ein Analysemodell, das alle Wände im Raum bedecken kann, wenn es in Times New Roman, 8pt gedruckt wird, weit über sein Ziel hinausgeschossen ist, einige dringende geschäftliche Bedürfnisse zu vermitteln. Verfasst von
Maarten Winkels
Unsere Ideen
Weitere Blogs
Contact
Let’s discuss how we can support your journey.



