DeathAndPain hat geschrieben: ↑16.03.2020 15:51
Das ist das generelle Ding, dass Attribute letztlich nichts anderes sind als globale Variablen, wobei der Scope natürlich je nach Kontext ein anderer ist. Manche Apologeten sagen, "global" seien nur Felder, die im DDIC stehen, aber das ist praxisfernes Theorycrafting
(so dass es sich mangels Praxisrelevanz nicht lohnt darüber nachzudenken, ob sie recht haben oder nicht, womit ich insbesondere andeuten möchte, dass ich das nicht bestreite). Die Aufgabe, eine saubere Kapselung innerhalb eines Programmes zu erreichen, damit seine Teile sich ohne Durchackern des Restprogrammes gut verstehen lassen, weil man sieht, was reingeht und was rauskommt, wird durch Attribute genauso konterkariert wie durch globale Variablen alter Schule. Das gilt selbst für Instanzattribute. Die sind zwar ans Objekt gebunden, aber die zu einem Objekt gehörende Klasse kann ja viele, viele Zeilen Coding umfassen. Und wenn man in einer Methode sieht, wie ein Attributwert benutzt wird, dann legt man sich genauso die Karten, wo dieser Wert herkommt und welche Bedeutung er hat, denn vom Aufrufer der Methode stammt er nicht (da nicht Teil der Methodenparameter), sondern ist irgendwann vorher mal von irgendwelchem anderen Coding innerhalb der Klasse gesetzt worden. Genau wie der Inhalt eines globalen Feldes auch.
Dabei ist mir klar, dass Attribute dem Zweck dienen sollen, Objektzustände herzustellen. Die wenigsten Attribute, die man in freier Wildbahn findet, erfüllen allerdings mit erkennbarer Durchdachtheit diesen Zweck; der weitaus überwiegende Teil wird erkennbar aus Faulheit des Programmierers als einfache globale Variable genutzt, wobei ebendieser Programmierer sich dennoch eilfertig darauf herausreden wird, modern-objektorientiert zu arbeiten und dadurch eine gute Kapselung zu haben.
Der oft gehörte Rat, auf Attribute nicht direkt zuzugreifen, sondern dies in GET/SET-Methoden zu verbergen, bringt auch nicht mehr, als nicht direkt auf Speicherzellen zuzugreifen, sondern dies durch die ABAP-Klassiker EXPORT TO MEMORY/IMPORT FROM MEMORY zu verbergen. Hier wie dort ist nicht transparent, wo die Daten herkommen und wo sie am Ende hingehen.
Also so ein paar Einsprüche habe ich da.
1. Ich würde im OO Bereich Typdeklarationen immer im DDIC machen und auf lokale Definitionen in Klassen verzichten. Gerade bei komplexeren und größeren Projekten zahlt sich das aus und eine Verwendung des Typs ist schnell gefunden, was u.a. eventuelle unbedachte Anpassungen erleichtert.
2. Wenn eine Klasse viele, viele Zeilen umfasst ist sie vermutlich zu groß und schlecht designt. Hier empfiehlt es sich immer im Baukasten-Prinzip zu arbeiten und die Teile zu etwas großem zusammen zu stecken.
3. Attribute mit globalen Variablen zu vergleichen trifft nur im Kontext zu, dass man eine Klasse als eigenes Programm sieht. Und da ist auch kein Problem. Grundsätzlich gibt es bis auf eine mir bekannten Fall( da ist es ein Interface-Attribut ) keine Rechtfertigung auf einen Setter/Getter zu verzichten. Public Attribute sind bei komplexeren Programmen .
4. Mir erscheint du erwartest beim Lesen eines Codings mit dem Lesen einer einzigen Seite eines Buches, den ganzen Roman zu kennen. Wo ist dein Problem in einer Methode ein an anderer Stelle gesetztes Attribut zu verwenden ? Dafür ist u.a. auch ein Constructor da. Oder eben ein Setter/Getter. Mit leerem Tank fährt auch kein Auto.
Beispiel : Ein CAO liest sich bei seiner Erzeugung einmalig den Inhalt der Customizing-Tabelle. Alle Methode des CAO operieren auf diesen Datenhaushalt, ergo das Attribut. Für dich ist zum Verstehen einer Methode erstmal völlig irrelevant woher der Wert kommt. Es zählt zu sehen, was damit passiert. Gerade wenn man den Fall hat, das der Inhalt eines Attributs geändert wird, sind Setter und Getter umso wichtiger. Denn der Verwendungsnachweis zeigt dir dann die Stellen an wo der Inhalt geädert wird und unterscheidet zwischen der Verwendung des Attributs in der Klasse. Das Paradigma : Keine Public-Attribute hat seinen Sinn. Schon weil das Objekt sonst keine Möglichkeit mehr hat, auf unerwünschtes Ändern seiner Attribute zur reagieren. Problem ist sicher, das es eine Menge schlechter Beispiele gibt. Auch sich an SAP Standardklassen zu orientieren ist nicht immer die beste Wahl. SAP selbst, hat da einige Prinzipien ausser Acht gelassen und kapselt und atomarisiert nicht genug.
Man muss sich VOR dem Erstellen einer Klasse erstmal Gedanken machen was für eine Art Klasse es überhaupt ist. Ein DTO ist anders als ein Service, ein Unit-Service anders als ein normaler. Ein Transaktionsservice wieder anders. So lange aber stumpf los gecodet wird, wie es viele der SAP Auftragsentwickler ( machmal macht es die vermeintlich langjährige Erfahrung noch schlimmer) tun, so lange wird es immer wieder schlechte Objekte geben.
Eine Klasse ist nun mal kein Report. Wenn man einen Report wie ein Objekt aufbauen würde oder aus OO-Sicht betracht, betreibt dieser letztlich nicht viel anderes als Messaging. Er erzeugt Objekte und reicht Dinge an andere Objekte weiter, sei es an einen Protokollhandler, einen Service usw. Er sorgt nur für den Kontrollfluss.