Laden...

Querverbindungen zwischen Klassen - OOP

Erstellt von wickedcsharper vor 13 Jahren Letzter Beitrag vor 13 Jahren 3.487 Views
wickedcsharper Themenstarter:in
160 Beiträge seit 2008
vor 13 Jahren
Querverbindungen zwischen Klassen - OOP

Hallo,

in unserer Software gibts die Klasse Rechnung.
Diese Klasse erbt von VorgangmitWarenkorb.

Nun Gibts die Klasse Warenkorb, die Über Aggregation eine Member der Klasse
VorgangmitWarenkorb und eine Member Rechnung kennt.

Die Klasse VorgnagmitWarenkorb kennt hat aber auch einen member Warenkorb.

Sinn soll sein dass die Rechnung ein VorgangmitWarenkorb ist, der Warenkorb selber aber auch einen VorgangmitWarenkorb hat und der vorgangmitWarenkorb letztlich weiss, welcher Rechnung er entstammt.

Meine Frage: Hier sitzen alte Programmierhasen (20-35 Jahre Erfahrung), aber macht man das so????? 🤔

„Wenn man eine Katze auseinandernehmen will, um zu sehen, wie sie funktioniert, hat man als erstes eine nicht funktionierende Katze in den Händen.“

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo wickedcsharper,

in unserer Software gibts die Klasse Rechnung.
Diese Klasse erbt von VorgangmitWarenkorb.

Vererbung ist eine IST-EIN-Beziehung. Das heißt, eine Rechnung wäre bei dir ein VorgangmitWarenkorb. Das ist natürlich Quatsch. Also die Vererbung stimmt hier schon mal nicht.

Außerdem sind Klassennamen wie XMitY schon mal verdächtigt.

Ansonsten sollten Klassen möglichst nicht zyklisch von einander abhängig sein. Die einzige Ausnahme ist, wenn die Klassen untrennbar zusammengehören. Also TreeView darf TreeNode kennen und umgekehrt, weil eine Klasse ohne die andere sowieso keinen Sinn macht. Aber normalerweise sind solche Zyklen unbedingt zu vermeiden.

Siehe auch Galileo <openbook>: Praxisbuch Objektorientierung von Bernhard Lahres, Gregor Raýmanl.

herbivore

5.941 Beiträge seit 2005
vor 13 Jahren

Hallo wickedcsharper

Sobald du ein Verbindungswort wie bspw. "und", "mit", "oder", ... in einem Klassennamen hast, ist schon was falsch.
Stichwort SOC: Seperation of concerns.
Beschreibung: Eine Klasse sollte nur eine Zuständigkeit besitzen.

Auf Methodenlevel kann man das auch anwenden: Eine Methode soll nur eine Sache tun.

Noch weiter gehts mit "Command / Query seperation".

Am besten guckst du mal in: http://clean-code-developer.de/

Mit anderen Worten: Ich würde das nicht so machen.

Ansonsten sollten Klassen möglichst nicht zyklisch von einander abhängig sein. Die einzige Ausnahme ist, wenn die Klassen untrennbar zusammengehören. Also TreeView darf TreeNode kennen und umgekehrt, weil eine Klasse ohne die andere sowieso keinen Sinn macht. Aber normalerweise sind solche Zyklen unbedingt zu vermeiden.

Volle Zustimmung.
Für Referenzen gilt dasselbe, nur dort sollte es noch strikter gehandhabt werden. (Wird schon von der IDE verhindert, oder gewarnt).

Gruss Peter

--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011

wickedcsharper Themenstarter:in
160 Beiträge seit 2008
vor 13 Jahren

danke euch beiden erstmal,

ich denke auch, dass es so quatsch ist - muss aber eine gute Argumentationsgrundlage haben. das Projekt ist natürlich "historisch gewachsen". Dafür habe ich Verständnis.
Aber das bekommt man ja immer zu hören, wenn im Nachhinein was verbastelt ist.

Was wäre denn ein logischer und "schöner" Aufbau?

Hat ein Warenkorb eine Rechnung - oder ist eine Rechnung ein Warenkorb - und wie ordnet man Angebot, Lieferschein und Auftrag in diese Thematik sinnvoll ein. Unter der Annahme, daß aus einem Angebot (mit Warenkorb) eine Rechnung (mit Warenkorb) und ein Lieferschein gedruckt werden kann?

Vielleicht hat ja einer eine kaufmännisch sinnvolle Klassenhierarchie Idee 👅

„Wenn man eine Katze auseinandernehmen will, um zu sehen, wie sie funktioniert, hat man als erstes eine nicht funktionierende Katze in den Händen.“

2.298 Beiträge seit 2010
vor 13 Jahren

Hallo,

meine Herangehensweise wäre, dass ein Warenkorb immer mindestens 1 Angebot hat, genau eine Rechnung und einen Lieferschein.

Soll heißen, du hast die Instanz von Warenkorb welche eine Liste von Angeboten enthält und jeweils eine Rechnung und einen Lieferschein. - Dabei erben jedoch keine der 4 Klassen untereinander.

// Edit um die Vorgänge nicht außer Acht zu lassen 😃
Eine Auflistung der Vorgänge hat auch die Klasse Warenkorb.

Der Warenkorb kennt dann sowohl Angebote, Rechnung, Lieferschein wie auch Vorgänge. - Angebote, Rechnung und Lieferschein wissen jedoch nichts über den Warenkorb.

Der Warenkorb gibt dann benötigte Informationen an die Angebote, Rechnung und Lieferschein weiter.

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

5.941 Beiträge seit 2005
vor 13 Jahren

Hallo wickedcsharper

So einfach wie möglich, so komplex wie nötig. Wobei zweiteres eine deutlich niedrigere Priorität hat und du jedes Problem, sei es noch so komplex, schlussendlich auch simpel abbilden kannst.

Das Geheimnis liegt in den Zuständigkeiten, Anzahl und Verbindungen / Abhängigkeiten der Typen.
Und schlussendlich, das du mit Blackboxes arbeitest (Komponenten mit einer öffentlichen Schnittstelle) und das was du im Moment wissen musst, um was zu ändern, so simpel wie möglichst hältst.

Das ganze System an sich, wird dann durch die oben genannten Dinge komplexer, je komplexer die Problemstellung ist.
Aber auch hier kann man das Thema an sich wieder trennen und in Richtung logische Modularisierung arbeiten.

Gruss Peter

--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011

wickedcsharper Themenstarter:in
160 Beiträge seit 2008
vor 13 Jahren

Hallo,

die genannte Architektur ist ja nicht auf meinem Mist gewachsen. Das das eine schlechte Architektur ist, war mir soweit auch klar. ich suche nur nach konstruktiven Verrbesserungsvorschlägen. Der Hinweis ich solle mich nochmal tiefer mit OOP beschäftigen wäre dann wohl meinen Kollegen vor 4 Jahren zu empfehlen gewesen.

Das Problem ist, das die Software zunehmend komplex wird und mit 420 zeilen Code (und 8 Programmierern) immer komplexer wird. ich stelle mir die Frage ob man ein deratiges Projekt noch redesignen kann?

Nochmal zum Thema:
ich würde jeweils folgende Klassen konzipieren: Angebot, Auftrag, Lieferschein und Warenkorb, eventuell noch einen Vorgang.

Zum Vorgang wird ein Angebot erzeugt. Dieses kann in einer gleich lautenden Tabelle abgelegt werden. Soll aus einem Angebot ein Auftrag erzeugt werden, werden die Daten aus der Tabelle Angebot gelesen und nach Speicherung in die Tabelle Auftrag gespeichert. Bei Rechnungserstellung kommen die Daten aus der Tabelle Auftrag und werden nach Rechnungserstellung in der Tabelle Rechnungen gespeichert.

Ich weiss nur noch nicht, wie man sinnvoll die Klasse Warenkorb in diese Struktur einbinden sollte. Der Warenkorb füllt sich ja nach und nach mit Artikeln. Sollte man den Warenkorb eventuell auch in einer separaten Tabelle speichern?

danke Peter,

das ist genau mein Versuch. Dieses Monsterprojekt zu vereinfachen....

danke für eure Hilfe

„Wenn man eine Katze auseinandernehmen will, um zu sehen, wie sie funktioniert, hat man als erstes eine nicht funktionierende Katze in den Händen.“

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo wickedcsharper,

Der Hinweis ich solle mich nochmal tiefer mit OOP beschäftigen wäre dann wohl meinen Kollegen vor 4 Jahren zu empfehlen gewesen.

sicher auch denen, aber natürlich auch dir. Die Architektur ist das eine, deine Fragen dazu das andere. Und aus denen lässt sich ableiten, dass der Rat schon ganz angebracht ist. 😃 Das richtet sich ja auch nicht gegen deine Qualifikation als Programmierer, sondern nur auf einen bestimmten Bereich, der augenscheinlich neu für dich ist.

herbivore

Gelöschter Account
vor 13 Jahren

das die Software zunehmend komplex wird und mit 420 zeilen Code (und 8 Programmierern) immer komplexer wird.

420 Zeilen Code kann gar nicht komplex sein. Es sei denn du meinst die Programmiersprache "Brainfuck".

wickedcsharper Themenstarter:in
160 Beiträge seit 2008
vor 13 Jahren

@herbi
ich will nicht gesagt haben dass ich nichts mehr dazulernen brauche.
mit jedem Tag, mit dem ich mich (ausser der Programmierung) mit bestimmten Themen beschäftige wird mir klar, wie wenig ich noch weiss 😉)

„Wenn man eine Katze auseinandernehmen will, um zu sehen, wie sie funktioniert, hat man als erstes eine nicht funktionierende Katze in den Händen.“

771 Beiträge seit 2009
vor 13 Jahren

bei

420 zeilen Code (und 8 Programmierern) ...

habe ich auch erstmal vor mich hin lachen müssen -)

Zurück zum Thema:
ich denke, inflames2k hat die Klassen schon ganz richtig dargestellt. Vererbung sollte man nur nutzen, wenn man auch wirklich Polymorphie (d.h. die Verwendung von virtuellen Methoden/Eigenschaften) benötigt und auch einsetzt (nicht um ein paar Zeilen Code zu sparen!).

wickedcsharper Themenstarter:in
160 Beiträge seit 2008
vor 13 Jahren

die eingangs erwähnte Problematik:

Klasse VorgangmitWarenkorb

Außerdem sind Klassennamen wie XMitY schon mal verdächtigt.

Genau hier möchte ich nochmal ansetzen.
Warum ist eine solche Klasse suspekt?

was impliziert eine solche Klasse, was aus OOP Gründen falsch ist?

„Wenn man eine Katze auseinandernehmen will, um zu sehen, wie sie funktioniert, hat man als erstes eine nicht funktionierende Katze in den Händen.“

5.941 Beiträge seit 2005
vor 13 Jahren

Salute wickedcsharper

Genau das was ich hier schrieb: Querverbindungen zwischen Klassen - OOP

Du musst es nur umkehren, dann weisst du was das impliziert.

Um es klar zu sagen: Das impliziert das die Klasse mehrere Zuständigkeiten hat / haben soll / möglicherweise hat.

Gruss Peter

--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011

2.187 Beiträge seit 2005
vor 13 Jahren

Hallo wickedcsharper

Um einen Design/Architektur-Vorschlag zu machen müssten wir wissen, was ein Warenkorb und ein Vorgang usw. können soll.
Fals das noch nicht klar ist welche Klasse was können soll, braucht man für einen Vorschlag die allgemeinen Anforderungen.

Gruß
Juy Juka