Code: Alles auswählen.
DATA(year2019) = NEW year( 2019 ).
year2019->wish( 'Happy new year' ).
Naja, es leidet dennoch die Testbarkeit und lesbarkeit. ich finde:deejey hat geschrieben:Ich habe relativ grobe OO-Kenntnisse, musste erst nachlesen was Singleton überhaupt bedeutet aber ich frage mich warum es wichtig ist wie viele Parameter der Constructor hat? Auch bei Erweiterungen sehe ich das Problem nicht, das Konzept optionaler Parameter ist doch perfekt und deckt vieles ab!? Und wenn es nicht optional ist, dann müssen eben alle Aufrufe angepasst werden, denn die fachliche Anforderung des neuen Parameters hatte ja einen Grund, den man meist nicht vorab ahnen konnte oder wollte.
Code: Alles auswählen.
new Year( year = '2019'
wish = 'Happy new Year'
people_on_earth = 8.000.000.000 " nicht wirklich
etc = etc
usw = usw ).
Code: Alles auswählen.
data(year) = Year=>get_instance( year = '2019' ).
year->set_wish( 'Happy new Year' ).
year->set_people( 8.000.000.000 ).
year->set_etc( etc ).
year->set_usw( usw ).
- das muss er aber auch bei einem private. Wenn man irgendwie "von außen" ein Attribut verändern möchte, muss man wissen wie das Beschaffen ist, sonst funktioniert das keinesfalls. Oder übersehe ich hier etwas?"Aufrufer muss über Parameter / Attribute bescheid wissen"
Code: Alles auswählen.
" gut lesbarer einzeiler, oder?
new Year( '2019' )->wish( 'Happy new Year' ).
Code: Alles auswählen.
data(greetings) = newYearGreetings=>get_instance( new Year( Year=>enum-2019 ) ).
greetings->wish( ). " output is 'Happy new Year'
Code: Alles auswählen.
" entweder - ist leichter zu lesen, wenige Parameter vorausgesetzt
data(year2019) = Year=>get_instance( Year=>enum-2019 ).
" oder - finde ich aus wartungs- und testsicht besser
data(2_year2019) = Year=>get_instance( ).
2_year2019->set_year( Year=>enum-2019 ).
year2019 = 2_year2019.
year2019->wish( 'Happy new Year' ).
year2019->vergesse_vorsätze( abap_true ).
" ...
Ich halte das Konzept der optionalen Parameter für schlecht in der Form wie es jetzt besteht. Hier wird oft versucht mehrere ähnliche use-cases in einer Methode zu erschlagen und das wird dann über eine jeweilige Kombination von optionalen Parametern erreicht. Wenn es in ABAP überschreibbare Methoden gäbe, würden die optionalen Parameter auch wirklich Sinn machen. Da ist optional dann auch echt optional und nicht ein hässliches "entweder so oder so, aber eins von den beiden Kombinationen musst du schon bedienen, sonst dumpts".deejey hat geschrieben:...das Konzept optionaler Parameter ist doch perfekt und deckt vieles ab!?
Das hängt immer vom Einzelfall ab. Ein Singleton nutzt man, wenn man nur ein Objekt braucht. Ich brauche keine n Instanzen einer Persistenzklasse, um n MARA-Sätze zu speichern, sondern nur eine. Ich brauche auch nicht n Instanzen einer UI-Klasse für einen Dialog. Ein Singleton schützt mich einfach davor, versehentlich den Speicher mit Instanzen zuzunageln.ewx hat geschrieben:Hallo zusammen,
in der letzten Zeit sind vermehrt Themen und Diskussionen aufgetaucht, die sich um die "richtige" Definition und Instantiierung von Objekten dreht.
- Singleton
- Multiton
- Factory
- get_instance
- Constructor-Parameter (ja, nein, wie viele?)
- usw
Wenige Parameter sind immer gut, keine sind noch besser, das gilt nicht nur für Konstruktoren, schon der vielen Testtupel wegen. Wenn man viele Parameter hat, sind sie in der Regel (nach meiner Erfahrung) schlecht oder gar nicht zusammengefasst. Wenn mehrere Variablen einen semantischen Zusammenhang haben, gehören sie in eine Struktur oder ein Objekt.ewx hat geschrieben:
- Was sind die Vorteile, wenn ein CONSTRUCTOR keine/wenige/viele Parameter hat?
- Was sind die Nachteile?
- Wie verhält es sich bei Erweiterungen, also wenn Parameter hinzukommen müssten?
- Lässt sich das umgehen? Wenn ja, wie?
- Worauf muss man aufpassen?
- Wie sieht ein Beispiel aus der Praxis aus?
- Wo gab es bei bisherigen Projekten Schwierigkeiten? Welche? Wie wurden sie gelöst?
- Wann ist ein singleton *wirklich* sinnvoll?
Wo DU dann schreibst, was für tolle Ideen du hattest? LOLewx hat geschrieben: Natürlich sollen am Ende ein oder mehrere Artikel im Tricktresor dabei herauskommen, in dem man alles gesammelt nachlesen kann...!
Folgende Benutzer bedankten sich beim Autor ralf.wenzel für den Beitrag (Insgesamt 2):
ewx • Tommy Nightmare
Ganz genau!Ralf.Wenzel hat geschrieben:Wo DU dann schreibst, was für tolle Ideen du hattest? LOL
Folgende Benutzer bedankten sich beim Autor a-dead-trousers für den Beitrag:
ewx
Folgende Benutzer bedankten sich beim Autor ralf.wenzel für den Beitrag:
a-dead-trousers
Sorry, wenn man eine Methode (theotetisch) durch eine ander ersetzen kann, war für mich das immer "überladen", aber du meinst das "überladen" einer Methode auch mit anderen Parametern, was in ABAP natürlich leider von jeher nie funktioniert hat. Peinlich jetzt, dass ich mich an die genaue Bezeichnung für diese Art der Methoden-Ersetzung nicht mehr erinnern kann.ralf.wenzel hat geschrieben:Du solltest aber ein wenig auf deine Wortwahl achten: Du meinst z. B. etwas anderes als überladen (das Überladen von Methoden wird in ABAP grundsätzlich nicht unterstützt). So kommt es leicht zu Missverständnissen.
Du suchst nach dem Wort „Redefinieren“.a-dead-trousers hat geschrieben:Sorry, wenn man eine Methode (theotetisch) durch eine ander ersetzen kann, war für mich das immer "überladen",ralf.wenzel hat geschrieben:Du solltest aber ein wenig auf deine Wortwahl achten: Du meinst z. B. etwas anderes als überladen (das Überladen von Methoden wird in ABAP grundsätzlich nicht unterstützt). So kommt es leicht zu Missverständnissen.
Das ist ein Paradebeispiel dafür, dass ich mich manchmal bei Ralfs Ausführungen frage: "Warum" oder "Was zum Geier meint er hier"?ralf.wenzel hat geschrieben:Ich hatte neulich den Fall, dass jemand Datum und Uhrzeit an eine Methode übergeben hat, damit sie sich einen Zeitstempel errechnen kann. Ersetzt habe ich die zwei Parameter durch ein Interface, das von einer Klasse implementiert ist, die einen Zeitstempel ermittelt. So habe ich nur einen Parameter und wenn ich zum Zeitstempel noch etwas anderes brauche (meinerwegen einen zweiten), ändere ich die Schnittstellendefinition, einen optionalen Parameter brauche ich dazu nicht. Bei einem Parameter ohne Verhalten reicht dann auch eine tiefe Struktur. Aber oftmals kommt dann eben doch Verhalten dazu....
Code: Alles auswählen.
lv_timestamp = get_timestamp( iv_datum = ... iv_uzeit = ... ).
...
method get_timestamp.
berechne irgendwie den Zeitstempel
endmethod.
Code: Alles auswählen.
lo_implementation = get_instance_timestamphelperclass( ... ).
lo_implementation->set_time( ... ).
lo_implementation->set_data( ... ).
Entweder das hier
lv_timestamp = get_timestamp( lo_implementation ).
oder das hier
lv_timestamp = lo_implementation->get_timestamp( ).
method get_timestamp.
berechne irgendwie den Zeitstempel
endmethod.
method get_implementation.
...
endmethod.
method set_time.
...
endmethod.
method set_data.
...
endmethod.
Es sieht nicht nur so aus - es ist deutlich! mehr Coding. Letztlich habe ich das Gefühl, als ob du eine (bisher wohl nur lokal) verwendete Methode in eine Helperklasse verschiebst. Macht ja bei mehrfach verwendbaren Methoden durchaus Sinn - aber das war irgenwie nicht der Tenor deiner ursprünglichen Ausführung.ralf.wenzel hat geschrieben:So ungefähr stimmt das, was du schreibst. Es sieht natürlich deutlich mehr aus, weil du „bei mir“ zwei Varianten zeigst. In Wahrheit verwende ich kaum mehr Coding als du.
Das machte die ursprüngliche Methode auch, indem sie hoffentlich 2 Pflichtparameter verlangt hat. Gibt halt verschiedene Wege nach Romralf.wenzel hat geschrieben:• Ich fasse die Daten zusammen, die zusammengehören
WAS?ralf.wenzel hat geschrieben:• Bei mir ändert sich die Methodenschnittstelle nicht, wenn die Definition des Timestamps sich ändert
Die hatte man vorher auch durch den Verwendungsnachweis der Methode.ralf.wenzel hat geschrieben:• Ich habe einen Verwendungsnachweis auf die Timestamp-Verwendungen
Nein, könnten zur Laufzeit ja ganz unterschiedliche Instanzen geholt werden. Je nachdem was man gerade benötigt. GET_INSTANCE ist einfach das delegieren der Instanzerzeugung, kann dann natürlich auch ein Singleton sein.black_adept hat geschrieben:
- Kann man eigentlich sagen, dass die Methode "GET_INSTANCE" eine Factory-Methode für den Singleton-Pattern ist?
Sollte so sein. Wenn Du eine separate Factory-Klasse hast, muss diese allerdings dann als "Friend" der eigentlich zu instantiierenden Klasse definiert werden.black_adept hat geschrieben:[/list]
- Sollte man bei Verwendung von Factories die Instanzerzeugung der Klasse auf "Private" stellen