Elementfunktionen vs. Nichtelementfunktionen in Java

temi

Top Contributor
Die Kernproblematik ist aus meiner Sicht: In Java geht es um eine Objektorientierte Entwicklung. Man soll also mit Objekten arbeiten.

Das static geht aber komplett an diesem Konzept vorbei.
Hallo zusammen,
aufgrund des obigen Zitates habe ich mich an eine Passage aus "Effective C++" von Scott Meyers erinnert, die da lautet:
Ziehen Sie nicht befreundete Nichtelementfunktionen den Elementfunktionen vor

Die Erläuterung dazu war (gekürzt) folgende:
Java:
class Browser {
    public clearCache();
    public clearHistory();
    public clearCookies();
}

Sollte man eine Funktion, die alles mit einem Aufruf löscht als Elementfunktion von Browser implementieren oder als "freie" Funktion?
Java:
class Browser {
    public clearCache();
    public clearHistory();
    public clearCookies();
    public clearAll(); // Möglichkeit 1
}

// oder

void clearAll(Browser br); // Möglichkeit 2, so in Java nicht möglich!

Sein Tipp ist es, eine Nichtelementfunktion zu implementieren, weil diese die Kapselung erhöht.

Die Argumentation dazu:
Kapselung bedeutet, etwas zu verbergen. Je stärker die Kapselung, desto weniger kann man sehen und je weniger man sehen kann, desto flexibler ist man als Programmierer etwas zu ändern. Das gilt für die mit dem Objekt verknüpften Daten insofern, je weniger Code die Daten sehen kann, desto stärker die Daten gekapselt sind. Deshalb ist eine Nichtelementfunktion vorzuziehen, weil sie nicht die Anzahl der Funktionen erhöht, die Zugriff auf die Daten haben.

Im Gegensatz zu C++ sind in Java ja freie Methoden nicht möglich. Die einzige Möglichkeit wäre es, diese als statische Methoden einer Klasse bereitzustellen. Wo wir wieder hier angekommen sind:
Die Kernproblematik ist aus meiner Sicht: In Java geht es um eine Objektorientierte Entwicklung. Man soll also mit Objekten arbeiten.

Das static geht aber komplett an diesem Konzept vorbei.

Was haltet ihr von dem Gedanken?
 
Zuletzt bearbeitet:

LimDul

Top Contributor
Ich halte davon gar nichts. Das Buch Effective C++ ist von 1992 - also quasi aus der Steinzeit. Ich behaupte das zum einen da vieles überholt ist.

Auf Java bedeutet das Konzept meines Erachtens auch nicht statisch verwenden sondern sagt nur "Methoden, die nicht auf den Daten einer Klasse A arbeiten habe nichts in Klasse A verloren". Und das würde ich auch unterschreiben - das heißt aber nicht, dass die Methode statisch werden soll, sondern das sie Klasse A ggf. nichts verloren hat.
 
K

kneitzel

Gast
Also ich kann die Gedanken vom Effective C++ nachvollziehen, aber wirklich zustimmen tue ich dem nicht. Aber das kann an meiner eingeschränkten C++ Sicht liegen. Also selbst in C++ würde ich dem derzeit so nicht folgen wollen.

Mir gefällt schon der Aufruf clearAll(browser) nicht. Das schränkt mich doch schon ein.... Ich spinne mir einfach mal etwas zusammen:
Ich habe einen SuperBrowser. Der hat halt einen Browser erweitert. Egal mit was. Der hat jetzt noch ABC und XYZ. Und ein clearAll() hat jetzt natürlich das übergeordnete clearAll() als auch das clearABC() und clearXYZ().
Wie Überschreibe ich das jetzt? Einfach nur per Polymorphie? Kann ich denn dann jetzt gezielt aus meinen clearAll(SuperBrowser) das clearAll(Browser) aufrufen? Im Augenblick fällt mir da dann pauschal Namespaces an. Also ich rufe BrowserNamsespace::clearAll(..) auf...

Aber evtl. gibt es da noch Möglichkeiten, die ich nicht (mehr) kenne.

Daher würde ich aus Designgründen und damit meine Klasse erweiterbar ist, das in der Klasse halten. Denn da gehört diese Methode aus meiner Sicht hin.
 

temi

Top Contributor
Das Buch Effective C++ ist von 1992
3. Auflage 2011. Und ja, manches könnte überholt sein, aber das Beschriebene ist meines Erachtens nicht ausschließlich auf C++ beziehbar (bis auf die befreundeten und nicht befreundeten Nichtelementmethoden) sondern generell auf die objektorientierte Programmierung übertragbar.
das heißt aber nicht, dass die Methode statisch werden soll, sondern das sie Klasse A ggf. nichts verloren hat
Ja, damit hast du natürlich recht. Es muss nicht zwangsläufig auf statische Methoden hinauslaufen.
 
Zuletzt bearbeitet:

thecain

Top Contributor
Was haltet ihr von dem Gedanken?
Die Idee an sich ist ja nicht doof, diese Funktionen zusammenzufassen, dann muss aber ganz klar definiert sein, was die Schnittstelle dieser Klasse ist, sonst läuft man in Probleme die schon @JustNobody erwähnt hat.

Static per se finde ich nicht doof, in dem Fall jedoch nicht sinnvoll. Für mich sollte ein static Methode möglichst keinen State ändern(auch kein Objekt) sondern dann ein neues zurück geben.

C++ ist auch eine Sprache die das OOP Paradigma noch weniger konsequent anwendet als Java. Von daher würde ich jetzt C++ Best Practices, wenn es denn welche sind, nicht unbedingt auf Java anwenden.
 

LimDul

Top Contributor
Das von @JustNobody und @thecain würde ich unterschreiben. Ich halte die Sicht (ob die jetzt C++ oder der Tatsache das die Grundlagen älter sind geschuldet sind) für zu eingeschränkt.

Es gibt eine Schnittstelle die eine Klasse anbietet. Und diese Methoden gehören als Klassen-Methoden da rein! Ob die Methoden auf die Daten der Klasse zugreifen oder nicht, ist eigentlich vielleicht irrelevant. Daten sind Implementierungsdetails. Wenn ich in dem Beispeil die clearAll Methode aus der Klasse raus ziehe gebe ich das Implementierungsdetail - das clearAll genau die 3 Methoden aufrufen soll - nach außen. Das heißt, die Funktionalität clearAll ist keine Funktionalität der Klasse Browser. Zu welcher Fachlichen Entität gehört sie dann? Wenn man diese Frage sinnvoll beantworten kann, ist klar wo die Methode hingehört - und das in dem Beispiel höchstwahrscheinlich doch die Klasse Browser.

Aus Sicht von außen hat eine Klasse keine Daten - sondern nur Methoden. Und ob und auf welchen Daten die arbeiten ist vollkommen egal -relevant ist, dass der Nutzer ein in sich konsistentes API hat.
 
K

kneitzel

Gast
Statische Methoden, die neue Objekte erzeugen, sind natürlich auch ein Beispiel für statische Methoden, die ich vergessen habe, aufzulisten. So eine parse Methode habe ich in der Praxis durchaus öfters...
 

LimDul

Top Contributor
Mir ist noch was eingefallen - Nehmen wir mal Test Driven Development. Wie entwickele ich da?

Ich fange an, in dem ich einen Test schreibe, Das heißt, ich erwarte, dass (um mal beim obigen Beispiel zu bleiben), dass ich eine Klasse Browser habe, mit der ich Dinge tun kann. Und das kann z. B. sein, dass ich TestDriven anfange "Ich kann alle Temporären Daten, History, Cookies, Cache" löschen. Das heißt, ich fange an der Stelle mit der Methode clearAll() an. Wenn die fertig ist, schreibe ich den nächsten Test - ich möchte nur Cookies löschen können - die Methode clearCookies() entsteht. Im Zuge des Refaktorings delegiert clearAll() dann an clearCookies() (da man doppelten Code vermeiden will). Am Ende sieht dann die Methode clearAll() so aus, dass sie nur noch eine Delegation ist. Es gibt aber jetzt keinen Grund im Refaktoring diese Methode rauszuwerfen oder zu verlagern.
 
K

kneitzel

Gast
Also das sehe ich anders. Du fängst ja klein an. Du willst einen Browser haben können und so ....
Dann hat er z.B. eine History.
Dann soll die gelöscht werden können => clearHistory
Dann kommen Cookies
Diese sollen gelöscht werden können also kommt clearCookies

Die Reihenfolge hier kann sich unterscheiden, aber ein clearAll macht erst Sinn, wenn es mind. 2 Dinge gibt, die gelöscht werden können ... die muss es also gegeben haben ...
 

LimDul

Top Contributor
Wobei es am Ende aufs gleiche rauskommt - du erwartest durc Tests definiert eine Methode clearAll am Browser-Objekt und ich sehe keine Refaktoring Ansatz der sagt "Ziehe es raus".
 
K

kneitzel

Gast
Wobei es am Ende aufs gleiche rauskommt - du erwartest durc Tests definiert eine Methode clearAll am Browser-Objekt und ich sehe keine Refaktoring Ansatz der sagt "Ziehe es raus".
Das ist natürlich richtig. Wobei bei der Implementation natürlich von Anfang an das entsprechende OO Design die Grundlage war. Daher ist das relativ logisch und erläutert auch, wieso ich beim rausziehen Bauschmerzen mit dem Design bekomme :)
 

temi

Top Contributor
Ist nicht die Klasse Collections genau das, was oben beschrieben wird?

Es gibt noch weitere Beispiele in der Java-Klassenbibliothek...
 

mihe7

Top Contributor
Möglichkeit 3:
Code:
class Browser {
    public:
        virtual void clearCache() = 0;
        virtual void clearHistory() = 0;
        virtual void clearCookies() = 0;
        void clearAll();
};

void Browser::clearAll() {
    this->clearCache();
    this->clearHistory();
    this->clearCookies();
}
 

LimDul

Top Contributor
Ist nicht die Klasse Collections genau das, was oben beschrieben wird?

Es gibt noch weitere Beispiele in der Java-Klassenbibliothek...
Das ist eine spannende Frage - Die Abgrenzung ist an der Stelle auch nicht trivial.

Die Klasse Collections bietet Methoden an um mit Collections zu arbeiten. Da kann man an vielen Stellen drüber diskutieren - ist es sinnvoll das in eine Extra Klassse zu packen oder wäre es nicht sinnvoller direkt in Collection aufgehoben.

Hier kommt ein "Problem" in Jave zu tragen. Java kann (aus gutem Grund keine Mehrfachvererbung). Und Collection ist ein Interface. Wenn nun z.B. jede Implementierung von Collection eine sort Methode implementieren muss ist das ziemlicher Bullshit - es sollte dafür eine Standard-Implementierung geben. Andererseits will man aber nicht eine Abstrakte Standard-Oberklasse Collection haben - weil damit schränkt man die Möglichkeiten zur Vererbung ein. Das heißt hier muss man einen Tod sterben:

a) Packe ich Kram in eine abstrakte Oberklasse, schränke ich die Möglichkeiten zur Vererbung ein
b) Definiere ich die Methoden nur im Interface, muss ich Implementireungen doppelt schreiben
c) Packe es in eine "Hilfsklasse" Collections hab ich Code, der fachlich eher Bestandteil der Collection-Api sein sollte in einer weiteren Klasse.
 

LimDul

Top Contributor
Wer ist das nicht? ;)

Der Punkt ist doch, dass Mehrfachvererbung mit den default-Methoden Einzug gehalten hat und da stellt sich natürlich die Frage: warum nur bei Interfaces und nicht bei Klassen?!?
Du kannst in Interfaces keinen Zustand halten in Form von Variablen. An der Stelle fängt es - zumindest in meinem Kopf - schnell an mit Mehrfachvererbung komplex und unüberschaubar zu werden. Ich kann in Interfaces auch nur public API definieren - während ich bei Klassenvererbung auch interne (protected) Methoden überschreibe.

Ich habe das Gefühl mit Mehrfachvererbung auf Klassenebene löse ich noch einige Spezialfälle mehr als mit Interfaces, schaffe auch mehr Stolpersteine und nicht mehr nachvollziehbares Verhalten.

Die Probleme gibt es auch jetzt schon mit den Default-Methoden in Interfaces. Da haben wir auch schon Probleme in Projekten gehabt.

Kontext: Wir haben in Firma eine Standard-Software, die wir dann bei Kundenprojekten in Form von Maven-Modulen nutzen und darauf aufbauend anpassen (Durch Vererbung, Komposition etc.). Da kam dann auch in einem neuen Release in einem Interface eine neue Methode mit Default-Implementierung hinzu. Problem: Im Kundenprojekt waren die anderen Methoden des Interfaces schon durch Kundenspezifisches Verhalten implementiert. Die neue Methode musste nun auch durch Kundenspezifisches Verhalten implementiert werden - aber dadurch das die ja eine Default-Implementierung hat, ist das erst relativ spät im Test aufgefallen. Hätte es keine Default-Implementierung gegeben, hätten wir eine Compile Error gehabt und es direkt angepasst.

Bei Merhfachvererbung sehe ich noch mehr die Gefahr, dass irgendwo oben in der Ableitungshierachie sich was ändert und auf einmal tickt die Klasse unten anders als vorher. Insbesondere wenn man die Klassen in der Ableitungshierachie nicht unter eigener Kontrolle hat.

Ob das wirklich so schlimm wäre weiß ich nicht - aber ich weiß auch nicht, ob der Benefit so groß wäre.
 

mihe7

Top Contributor
Du kannst in Interfaces keinen Zustand halten in Form von Variablen. An der Stelle fängt es - zumindest in meinem Kopf - schnell an mit Mehrfachvererbung komplex und unüberschaubar zu werden. Ich kann in Interfaces auch nur public API definieren - während ich bei Klassenvererbung auch interne (protected) Methoden überschreibe.
Das wäre alles kein Problem, ist jetzt ja auch nicht anders:
Java:
class Base {
    protected int value = 5;
}

public class Extension extends Base {
    protected int value = 10;
}
In einem Extension-Objekt gilt nun this.value == 10 und super.value == 5.

Natürlich wird Mehrfachvererbung komplex; das ist ja genau der Punkt: ohne default-Methoden gab es keine Mehrfachvererbung von Implementierungen. Mit den default-Methoden hat man sich nun die Komplexität sowieso schon ins Boot geholt, dann hätte man es gleich "richtig" machen können.

Interessant wäre das doch vor allem, wenn es sich um wirklich unterschiedliche Klassen handelt. Dann gibt es das Problem von Konflikten sowieso nicht (bzw. wenn, dann nur zufällig).

NB: das soll kein "pro Mehrfachvererbung" werden.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
G Umwandung von Vb auf Java Softwareentwicklung 1
von Spotz Kommunikation zwischen Java und Container Orchestrator (Microservices) Softwareentwicklung 11
S Microservices in Java Spring: Nebenläufigkeitsprobleme lösen Softwareentwicklung 6
R Umsetzungen in Java vs. Umsetzungen auf Datenbankebene Softwareentwicklung 9
L Module Eclipse Java 9 Softwareentwicklung 12
R Software-Architekt (Schwerpunkt Java) Softwareentwicklung 9
S VB.NET / C# als Java-Entwickler? Softwareentwicklung 2
J Java Kentnisse vertiefen oder andere Programmiersprache probieren? Softwareentwicklung 8
U Java vs. anderen plattformunabhängige Programmiersprachen Softwareentwicklung 8
S JNI Java from C Softwareentwicklung 0
H [Java]Regex Hilfe Softwareentwicklung 3
D Teamspeak Java html app Softwareentwicklung 5
N UML Komponenten als Java-Klassen abbilden Softwareentwicklung 4
S Java Anfänger hat Probleme mit Scanner Softwareentwicklung 6
C Lohnt es sich noch ein neues Projekt in C++ anstatt Java zu realisieren? Softwareentwicklung 4
U Java oder welche Sprache? Softwareentwicklung 98
MrWhite Ist Java gar nicht sooo objektorientiert??! Softwareentwicklung 16
J Java Long-Werte in C++ auslesen Softwareentwicklung 4
K Mit "Java" html-Seite entscripten Softwareentwicklung 6
Airwolf89 Theoretische Frage - In Java Java-Programme schreiben Softwareentwicklung 5
G Mischsprache aus Java & C# Softwareentwicklung 23
H COBOL und Java Softwareentwicklung 17
H Java als Backend, Javascript als View Softwareentwicklung 3
D Sind EJB Komponenten auch mit Java Swing nutzbar? Softwareentwicklung 8
U Decorator Pattern in der Java API Softwareentwicklung 6
J Java Software nach C++ portieren Softwareentwicklung 6
C Unterschiede: C++ vs. C# vs. Java Softwareentwicklung 21
G Umstieg Java/Oracle => C#/MSSQL Softwareentwicklung 13
A Jira durch Java ansprechen Softwareentwicklung 18
M Immutable Objekte und funktionales Programmieren in Java oder Scala Softwareentwicklung 34
B [Web 2.0] Java vs PHP Softwareentwicklung 28
Raidri Flex mit Java Softwareentwicklung 2
L Java + WCF Softwareentwicklung 9
Airwolf89 Java-Programm in C++ portieren Softwareentwicklung 4
T Kapselung nich vollständig umgesetzt in Java? Softwareentwicklung 4
J Korpus mit Python einlesen - weiterbearbeiten mit Java Softwareentwicklung 4
N c# nach java Softwareentwicklung 14
K Suche freies UML Tool um aus .java dateien Diagramme zu. Softwareentwicklung 8
D Java in KLassen, schon vorhanden? Softwareentwicklung 3
B Was ist besser für Grafiken? Java oder C#? Softwareentwicklung 9
R Java Passwort verschlüsseln --> kompliziert! wirklich doo Softwareentwicklung 13
F vorteile php gegenüber java? Softwareentwicklung 46
M Umwandlung von String in java.sql.Date Softwareentwicklung 2
lolkind Iso Datein per Java über Windows XP brennen Softwareentwicklung 13
U [Diskussion] Java vs. C# Softwareentwicklung 208
E Java Programm distributen Softwareentwicklung 35
J Hardware zugriff mit java? Softwareentwicklung 4
N Für und Wieder von Java und .NET (primär C#) | Performance Softwareentwicklung 6
G java.lang.ArrayIndexOutOfBoundsException Softwareentwicklung 5
E Default Java unter Linux aendern? Softwareentwicklung 3
S arabische Buchstaben in java ?:L Softwareentwicklung 3
L Noch 'ne Perl-Frage. Kehre dann auch reumütig zu Java zurück Softwareentwicklung 10
G Serveranbindung mit java Softwareentwicklung 24
P Grafik-Programm mit JAVA? Softwareentwicklung 21
G Umstieg von Delphi zu JAVA (wichtige Fragen!) Softwareentwicklung 41
F Welche Sprache sieht ähnlich aus wie Java? Softwareentwicklung 7
T Suche A Star Java Beispielprogramm Softwareentwicklung 2
D C# zu Java - Übersetzer gesucht. Softwareentwicklung 3
F Windows Media Player in Java? Softwareentwicklung 11
C C code in java umschreiben Softwareentwicklung 9
O java und c# - die zweite. Softwareentwicklung 7
S Problem PJIRC java-applet Softwareentwicklung 4
U Geeignete Plattform für Projekt (JSP, PHP, Java-Anwendung) Softwareentwicklung 7
G C++ in JAVA verpacken Softwareentwicklung 2
D C# vs. java Softwareentwicklung 16
G Darstellung von Java-Projekten mit UML Softwareentwicklung 3
E Java & Performance Softwareentwicklung 9
T Brauche für meinen Java-Code dringend Hilfe Softwareentwicklung 4
B Wo bekommt man fertige Java-Programme (z.B. für Lsg LGS) Softwareentwicklung 3
W Herangehensweise an ein Java Programm Softwareentwicklung 4
B Programmierung eines 8051-Assemblers unter Java Softwareentwicklung 3
M Bidirektionale Assoziazion in Java realisieren? Softwareentwicklung 3
J Java <-> C# Softwareentwicklung 1
S c# schneller java - wieso ? Softwareentwicklung 12
D C++ und Java Softwareentwicklung 61

Ähnliche Java Themen

Neue Themen


Oben