Guten Tag miteinander
Ich habe eine Frage zu Listen in Java.
Lohnt es sich Listen in Klassen mit "private" zu verstecken?
Wenn man dies tut muss man z.B. eine methode "add" schreiben. Diese tut
dann nichts anderes als einfach die methode "add" der private liste
aufzurufen. Deshalb frage ich mich ob es nicht klüger ist die Liste
gleich mit "public" zu deklarieren.
Freundliche Grüsse
Sandro
Sandro schrieb:> Deshalb frage ich mich ob es nicht klüger ist die Liste> gleich mit "public" zu deklarieren.
dann kann aber auch jemand clear aufrufen.
Peter II schrieb:> dann kann aber auch jemand clear aufrufen.
Zumal es sowieso Sinnfrei ist Interna dann wieder per Methode von
draußen zugreifbar zu machen und der Aufrufer muss dan wieder
irgendwelches Wissen mitbringen...
Sondern man hat eine Aufgabe (z.B. verwalten von X-Objekten) und dafür
hat man ggf. eine add/replace/remove Methode.
Ob man diese nun intern in einer Listen, Datenbank oder sonstwie
verwaltet ist uninteressant und sollte nicht interessieren (Kapselung).
Und schlussendlich ist das nicht nur in Java so...
>Sondern man hat eine Aufgabe (z.B. verwalten von X-Objekten) und dafür>hat man ggf. eine add/replace/remove Methode.
Naja, ich kann den TO verstehen. Wenn ich eh alle Methoden zur
vollständigen Manipulierung der Liste (add/replace/remove) über Methoden
verfügbar mache, warum nicht gleich die Liste öffentlich machen? Das
macht schon Sinn, wenn man so betrachtet.
Gruß Jonas
jonas biensack schrieb:> Naja, ich kann den TO verstehen. Wenn ich eh alle Methoden zur> vollständigen Manipulierung der Liste (add/replace/remove) über Methoden> verfügbar mache, warum nicht gleich die Liste öffentlich machen? Das> macht schon Sinn, wenn man so betrachtet.
dann hat sie erstens im entsprechenden objekt aber möglicherweise nichts
verloren, und zweitens möchte man vielleicht die art der listenobjekte
beschränken.
Der Sinn von Kapselung ist ja eher die Implementierung einer Whitelist.
Im Getter/Setter kann dann reguliert werden, ob und wie der Zugriff
erfolgen darf. Beispiel: Lazy Loading.
Je nachdem wie strikt die Liste gekapselt werden soll, gibt es dann eben
mehrere Methoden um nach Vorgabe die Liste zu bearbeiten. Wenn nur der
Zugriff auf die Liste an sich reguliert werden soll, reicht ein Getter.
Hallo Sandro,
wenn Du Dir die Frage stellst, ob sich private Member lohnen, dann hast
Du den Sinn der Objektorientierung und Datenkapselung nicht verstanden.
http://en.wikipedia.org/wiki/Information_hiding
Was, wenn Deine Klasse noch Zusatzoperationen ausführen möchte, wenn ein
neues Element der Liste hinzugefügt wird oder ein Element aus der Liste
entfernt werden soll? Kann der Benutzer Deiner Klasse die Liste direkt
verwenden, schaffst Du damit die Möglichkeit, all diese Mechanismen
auszuhebeln. Wann dann was wo mit der Liste passiert, kann man so dann
nicht mehr nachvollziehen, da es nicht mehr ausschließlich in dieser
Klasse passiert -> Spaghetticode.
Eine Klasse ist nicht einfach nur eine Ansammlung von Membern. Stell Dir
eine Instanz wie eine Person vor. Sie möchte Verantwortung übernehmen,
selbständig arbeiten und ihren Job gut machen, statt von der
Gutmütigkeit anderer Personen (Instanzen, Klassen) abhängig zu sein oder
sich von ihnen ständig hin- und herschubsen und mobben lassen zu müssen.
Grüße, Markus
Was soll die Klasse denn machen in der das Listenobjekt ist.
Wenn du alle Methden der Liste nach aussen sichtbar haben willst, dann
kannst du deine Klasse vieleicht auch von einer Liste ableiten.
jonas biensack schrieb:>>Sondern man hat eine Aufgabe (z.B. verwalten von X-Objekten) und dafür>>hat man ggf. eine add/replace/remove Methode.>> Naja, ich kann den TO verstehen.
Ich nicht.
Denn die 3 Methoden sind schneller geschrieben, als die Frage hier im
Forum.
> Wenn ich eh alle Methoden zur> vollständigen Manipulierung der Liste (add/replace/remove) über Methoden> verfügbar mache, warum nicht gleich die Liste öffentlich machen? Das> macht schon Sinn, wenn man so betrachtet.
Der Sinn einer Kapselung besteht darin, Implementierungsdetails zu
verstecken. Den Verwender der Klasse hat es nicht zu interessieren, dass
dahinter eine Liste steckt. Denn dann kann ich die Liste irgendwann
gegen eine andere Form der Datenhaltung austauschen, ohne dass sich für
den Verwender der Klasse irgendetwas ändert. Und wenn ich die Liste
gegen eine Speicherung in der Cloud austausche, ist ihm das auch egal.
Ein Verwender hat seine add/replace/remove Methode und wie die Klasse
das macht, die Operationen umzusetzen, ist nicht sein Bier.
Aus der Erfahrung heraus: Es sind sehr oft genau diese "Ooch, da mach
ich doch gleich alles public und jeder der will, der soll" Ansätze, die
auf lange Sicht in Programmen den meisten Ärger machen, weil sie
unweigerlich in die Situation führen, dass sich notwendiges Detailwissen
quer über das ganze Programm verteilt, anstatt an einer Stelle
konzentriert zu bleiben.
>Aus der Erfahrung heraus: Es sind sehr oft genau diese "Ooch, da mach>ich doch gleich alles public und jeder der will, der soll" Ansätze, die>auf lange Sicht in Programmen den meisten Ärger machen, weil sie>unweigerlich in die Situation führen, dass sich notwendiges Detailwissen>quer über das ganze Programm verteilt, anstatt an einer Stelle>konzentriert zu bleiben.
Ja. Es ging mir aber darum:
>dann hat sie erstens im entsprechenden objekt aber möglicherweise nichts>verloren...
Ich vermute eher das die Liste gar nichts in dem Objekt zu suchen hat.
Sondern an ganz anderer Stelle, nämlich da wo sie auch ständig verändert
wird.
Auf diesen Punkt wollte ich aufmerksam machen.
gruß jonas
und kleiner Nachtrag:
oft hat man ja nicht nur eine liste, sondern mehrere..
was ist wohl besser:
add
addtoListe2
addtoListe3
sort
sortListe2
sortListe3
removefromList2
removefromList3
insert
insertIntoList2
insertIntoList3
Clear
ClearList2
oder
List.add/sort/remove/insert/count/...
List2.add/sort/remove/insert/count/...
List3.add/sort/remove/insert/count/...
Robert L. schrieb:> und kleiner Nachtrag:>> oft hat man ja nicht nur eine liste, sondern mehrere..>> was ist wohl besser:>> add> addtoListe2> addtoListe3> sort> sortListe2> sortListe3> removefromList2> removefromList3> insert> insertIntoList2> insertIntoList3> Clear> ClearList2
keines davon.
Sondern ein
addMember
addClient
addCustomer
sortByMember
sortByCustomer
oder ein
sort( itemType ) // Member, Client, Customer
oder ein Objekt Client, welches aus den Teilen Name, Address und
PhoneNumer besteht und man hat dann ein
add( Client )
Das eine Klasse wirklich 3 Datencontainer hat, die voneinander
vollkommen unabhängig sind, ist eher die Ausnahme als die Regel.
Robert L. schrieb:> add> addtoListe2> addtoListe3
Besser wäre es wenn jede dieser Liste einen Namen hätte, der sinnvoll
aussagt was in der Liste ist.
Zum Beispiel
kunden.add()
addressen.add()
...
Und wenn du eine Klasse hast in der wirklich mehrere Listen sein müssen
dann hast du eben Methoden der Art
addKunde()
addAdresse()
...
Karl Heinz schrieb:> Das eine Klasse wirklich 3 Datencontainer hat, die voneinander> vollkommen unabhängig sind, ist eher die Ausnahme als die Regel.
Mit 'vollkommen unabhängig voneinander' meine ich auch wirklich komplett
und zu 100% voneinander unabhängig.
Ein geometrisches Objekt mag sich seine Oberflächen, Kanten und
Eckpunkte in 3 Listen halten. Aber die sind nicht voneinander
unabhängig. Wenn jeder der will, einfach Eckpunkte aus der einen Liste
rausschiesst, dann hat man schnell Chaos, weil dann Kanten auf Punkte
referenzieren, die nicht mehr existieren. Genau hier ist man gut
beraten, die Listen eben nicht (und wenn dann nur read_only) nach aussen
hin zur Verfügung zu stellen.
Karl Heinz schrieb:> Genau hier ist man gut> beraten, die Listen eben nicht (und wenn dann nur read_only) nach aussen> hin zur Verfügung zu stellen.
Schönes Beispiel, du willst dann sicher nicht, daß der Anwender von
aussen einfach Kanten oder Ecken dazufügt, dann hast du keine Kontrolle
ob das Objekt noch in sich konsistent ist.
In dem Fall hast du Methoden um das geometrische Objekt zu modifizieren
und keine um direkt die inneren Daten zu verändern.
>Ein geometrisches Objekt mag sich seine Oberflächen, Kanten und>Eckpunkte in 3 Listen halten. Aber die sind nicht voneinander>unabhängig.
Die aber auch wieder in eine Liste von Triangelobjekten umgeformt wird,
dise hat dann sämtliche Information (Oberflächen [hier fehlt die angabe
in welche richtung eine textur zeigt, Kanten, sowie die Eckpunkte).
Gruß Jonas
Robert L. schrieb:> oft hat man ja nicht nur eine liste, sondern mehrere
Was schert mich die INTERNE Datenstruktur... wenns die API erfüllt und
performant ist soll der doch von miraus hunder Listen, Sets, Maps oder
Maaß-Bier Objekte intern nutzen...
Und das schöne ist: Man darf auch mehr als eine Klasse nutzen um seine
Daten und Aufgaben passend zu partitionieren... es muss nicht die eine
God Object ( http://en.wikipedia.org/wiki/God_object ) geben was alles
erdenkliche enthält.
Robert L. schrieb:> oder
Wenn man wirklich immer GLEICHE Operationen hat würde man eine
Oberklasse/Interface definieren und dann halt:
object.getKundenVerwalter()
object.getProduktVerwalter()
welche dann die entsprechenden Operationen hat.
ich weiß schon was du meinst, aber:
>Wenn man wirklich immer GLEICHE Operationen hat würde man eine>Oberklasse
und diese oberklasse ist eben die TList, TObjectList
was auch immer
das Beispiel mit den Punken und Linien ist auch ziemlich "konstruiert"
niemand hindert dich , beim löschen eines Punktes eine z.b. exception zu
werfen, wenn der Punkt noch von einer Linie verwendet wird..
generell ist public listen sicher nich immer böses
(irgend ein Beispiel was mir gerad einfällt wäre:)
Hibernate mach z.b. public listen
https://docs.jboss.org/hibernate/orm/3.6/reference/en-US/html/collections.html
7.2.2.1. Lists
ps: vielleicht postet ihr auch mal CODE der "euer" system zeigt, und
nicht nur "gedankenexperimente"..
Markus schrieb:> blödes Beispiel. Dort geht's um Indexed Collections und nicht um> Software Design Prinzipien.
Vor allem ist die Liste selbst (orders) private, aber dank dem Property
Access (anstatt Field Access) wird einem dann der Getter aufgezwungen,
der Setter nach JavaBean Konvention verhindert dann auch Kapselung &
Information Hiding, JavaBeans sind eben Datenstrukturen, keine richtigen
Objekte nach OOP.
Selbst wenn public Listen so ziemlich jedem OO Konzept widersprechen,
sind JavaBeans artige Setter keine echte Verbesserung, letzeres aber zB.
fuer DTOs aber durchaus angebracht, kenne keinen richtigen
Anwednungsfall fuer public Listen.
Aber ein konkretes Beispiel waere wirklich besser um die Vor- und
Nachteile darzustellen.
Hi,
Mladen G. schrieb:> Aber ein konkretes Beispiel waere wirklich besser um die Vor- und> Nachteile darzustellen.
wozu? Der Entwickler merkt's schon am eigenen Leib, wenn er seinen
Spaghetticode nicht mehr blickt ... wenn er's denn blickt, daß er's
nicht mehr blickt ... und macht's beim nächsten mal - vielleicht -
anders.
Mir kommt auf Arbeit ständig Code unter aller Sau unter. Nicht jeder
blickt's beim ersten mal, manche offensichtlich nie. Die, die's blicken,
brauchen kein Beispiel, haben's selber gelernt. Bei den anderen nutzt
ein Beispiel nix.
Grüße, Markus
Markus schrieb:> wozu? Der Entwickler merkt's schon am eigenen Leib, wenn er seinen> Spaghetticode nicht mehr blickt ... wenn er's denn blickt, daß er's> nicht mehr blickt ... und macht's beim nächsten mal - vielleicht -> anders.
Leider laueft das oft anders, zB.
- nur noch derjenige kann bzw. will an dem Code weiterpfuschen
- externe die bald sowieso ueber alle Berge sind und die Einstellung
habven "nach mir die Sinnflut"
Das einzige Qualitaetsmerkal ist dann oft "bei mir lauefts".. :(
Robert L. schrieb:> Hibernate mach z.b. public listen
Gerade bei Hibernate wäre es tödlich ggf. einfach vertrauensvoll auf
"die Liste" zuzugreifen (und public ist die auch nicht), da dank
ByteCodeWeaving etc. da im Hintergrund ggf. schlimme Dinge passieren
(LazyLoading z.B.!) weswegen man hier in jedem Fall per Getter
zugreift/greifen muss.
> Fall per Getter
auf die Liste ja,
davon bin ich ausgegangen (siehe auch mein Delphi VCL Beispiel)
Felder pulbic macht doch sowieso niemand, egalb ob jetzt listen oder
primitive typen...
Robert L. schrieb:> Felder pulbic macht doch sowieso niemand, egalb ob jetzt listen oder> primitive typen...
Naja, je nach Anwendungsfall würde ich die Liste schon direkt
zurückgeben. In C# z.B. per Property vom Typ ReadOnlyCollection oder
IEnumerable.