| Autor |
Beitrag |
Flamefire
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: Mo 26.07.10 19:00
Habe mal eine OO-Design-Frage. Hab verschiedenen Ansätze, aber gefällt mir alles nicht so.
Situation:
Ich habe ein System, in dem ein User angemeldet ist. Der User hat bestimmte Inhalte, die ihm zugeordnet werden können (z.b. Nachrichten, Dateien, Posts)
Am Ende sollen die Daten aus einer Schnittstelle kommen.
(Fett=Eine Klasse)
Jetzt möchte ich das natürlich sinnvoll vererben und delegieren lassen.
Idee1: System hat User und Inhalte. Dann läuft das ganze so:
System.Login() -> User.Login()
System.GetContentAll() -> Contents.GetAll(User.GetID()) -> Interface.Get(Stream)
System.GetContent(id) -> Contents.Get(User.GetID(),id) -> Interface.Get(Stream)
usw.
Also praktisch brauch ich für so ziemlich jede Funktion einen Wrapper im System, der kaum was macht.
Alternativ wäre:
User erbt von Interface und kann somit direkt darauf zugreifen.
Content erbt von User: Kann damit auf Interface zugreifen und die User-ID direkt verwenden, da es ja eine Eigene Eigenschaft ist.
Damit umgehe ich die massenweise Wrapper klassen, hab aber in der Content klasse z.b. User-Funktionen mit drin, was ja auch nicht Sinn&Zweck der OOP ist...
Besserer Ansatz?
|
|
jaenicke
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mo 26.07.10 20:03
Was spricht denn dagegen einfach die User-Klasse (oder ein Interface mit eingeschränkter Funktionalität darauf) per Property sichtbar zu machen? Dann kannst du alles kapseln, brauchst gleichzeitig aber nicht für alles Wrapper zu schreiben.
|
|
Flamefire 
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: Mo 26.07.10 22:23
nja das problem ist ja auch, dass content zugriff auf die user ID braucht. und sowohl user als auch content brauch zugriff auf den connector.
ich könnte das den jeweiligen instanzen als referenz geben. wäre ne variante. oder gibts noch was besseres?
|
|
jaenicke
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mo 26.07.10 22:33
Der Content gehört dem Benutzer, nicht umgekehrt, dementsprechend sollte er auch nicht das User-Objekt direkt kennen. Ich habe das über ein außenstehendes Interface gelöst. Dieses stellt die benötigten Eigenschaften usw. zur Verfügung und nur das kennt in deinem Fall der Content. Implementiert wird das dann von deiner User-Klasse.
Auf diese Weise sparst du dir große Parameterübergaben, musst aber dennoch keine direkte Kreuzbeziehung hinbiegen.
Da die Referenzzählung dann nicht benötigt wird (schließlich gibst du die Objekte dann ja auch wieder frei), habe ich mir ein TIntfObjectNoRefCount (oder so ähnlich  ) abgeleitet, in dem ich die Interface-Methoden implementiert und die Referenzzählung dabei ausgeschaltet habe. Dann kann ich davon und von dem Interface ableiten.
|
|
Flamefire 
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: Mo 26.07.10 22:43
"Content gehört dem Benutzer" --> Benutzer müsste eine Instanz von Content haben
Nur ist für das Benutzerobjekt der Content vollkommen unwichtig. Andersrum nicht.
Also eher im Content eine Eigenschaft "Owner:TBenutzer"
Das mit dem Interface ist eine Variante. Wie könnte man das nennen? Eigendlich brauch ich ja nur die Id bzw den Namen... Und IBenutzer wäre eher ein Interface zum kompletten...
Referenzzählung von Objekten? Ich dachte Delphi hat sowas nicht (bzw nur bei Strings) Oder doch?
|
|
jaenicke
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mo 26.07.10 22:49
|
|
Flamefire 
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: Mo 26.07.10 23:03
jaenicke hat folgendes geschrieben : | Flamefire hat folgendes geschrieben : | | Nur ist für das Benutzerobjekt der Content vollkommen unwichtig. Andersrum nicht. | Nun, aber die logische Beziehung ist doch, dass der Benutzer Contents hat. Eben seine Nachrichten usw., so meinte ich das. |
Das meinte ich: Die logische Beziehung ist so rum. Aber die programmiertechnisch sinnvolle andersrum. Benutzer greift NIE auf Content zu, aber andersrum (fast) immer.
jaenicke hat folgendes geschrieben : |
Bei Interfaces gibt es das naturgemäß auch. Heißt wenn du ein Objekt über Interfaces ansprichst und deren Referenzzähler auf 0 geht, wird _Release und darüber Destroy aufgerufen. Das kannst du verhindern, indem du nur QueryInterface normal implementierst und _AddRef und _Release einfach immer 1 zurückgeben lässt, aber sonst nix darin machst. |
Ok...ist sehr ungewohnt, da ich Interfaces bisher als nicht implementierte TObjects gesehen habe. Also alles auf virtual.
Das da jetzt Referenzzählung reinkommt, hätte ich nciht erwartet. Also könnte ich mir von jedem Objekt, dass ich schreibe, ein Interface schreiben, das Objekt davon erben lassen und dann immer gegen das Interface implementieren. Schon habe ich in Delphi auch eine weitestgehend vollständige GarbageCollection und brauch mich nicht mehr um .Free() kümmern.
Ok ist Offtopic aber ein für mich interessanter Gedankengang.
|
|
|