OOP

jono

Top Contributor
Hallo,
Java:
import java.util.ArrayList;
import java.util.List;

public class Blyadflix {

    private ArrayList<Film> filme = new ArrayList<Film>();
    private Server server;
    private List<Person> personen = new ArrayList<Person>();
    private List<Kunde> abonnenten = new ArrayList<Kunde>();

    public Blyadflix(Film film, Server server) {
        this.filme.add(film);
        this.server = server;
    }
  
    public void addPerson(Person p) {
        if(p == null) return;
      
        personen.add(p);
        p.setPortal(this);
    }
  
    public void removePerson(Person p) {
      
    }
  
    public void filmHinzufuegen(Film film) {
        if(film == null) return;
      
        if(!this.getFilme().contains(film))
            this.getFilme().add(film);
    }

    public ArrayList<Film> getFilme() {
        return filme;
    }

    public void setFilme(ArrayList<Film> filme) {
        this.filme = filme;
    }

    public Server getServer() {
        return server;
    }

    public void setServer(Server server) {
        this.server = server;
    }

    public List<Kunde> getAbonnenten() {
        return abonnenten;
    }

    public void setAbonnenten(List<Kunde> abonnenten) {
        this.abonnenten = abonnenten;
    }

    public List<Person> getPersonen() {
        return personen;
    }

    public void setPersonen(List<Person> personen) {
        this.personen = personen;
    }

}
1. Wenn ich mir diese Klasse anschaue, frage ich mich, warum in der Methode "addPerson" über "personen.add(p)" geaddet wird und warum dann aufeinmal in Methode "filmHinzufuegen" "getFilme" geaddet wird, also warum einmal get und warum einmal nicht? Und ob das this. vor "getFilme" auch weggelassen werden könnte?
2. Wofür steht setPortal()?
 

Robert Zenz

Top Contributor
Weil die Person welch es geschrieben hat uneinheitlich war (sieht man auch am Mischmasch aus Englisch/Deutsch), ueberhaupt ist das Design der Klasse relativ schlecht. Einheitlichkeit ist, meiner Meinung nach, einer der wichtigsten Punkte um verstaendlichen und wartbaren Code zu erzeugen.

Zunaechst mal bin ich kein Freund des Standard "alles private" Ansatzes, ich finde der interne Zustand der Klasse sollte Erweiterungen der Klasse zugaenglich sein, also alle Variablen eher "protected" damit einen erweiterende Klasse die Chance hat die Logik auch tatsaechlich zu erweitern. Den internen Zustand der Klasse "private" zu haben, macht die meisten Klassen implizit "final" weil man ohnehin keine Chance hat etwas an der Logik zu aendern oder zu erweitern.

Dann akzeptiert die Klasse Listen und gibt die selben Instanzen auch wieder heraus in den Gettern. Das kann zu Problemen fuehren da sich die Instanz ausserhalb der Klasse veraendern kann, also die Methoden "addPerson" und so sind nicht die einzigen Punkte mit welchen Objekte hinzugeuegt werden koennen.

Was das Verwenden des Feldes gegenueber das verwenden eines Getters angeht, letzteres erlaubt es einer erweiternden Klasse den Getter zu ueberschreiben und somit zu beeinflussen auf welchem Wert die "interne" Logik der Basisklasse operiert. Wird aber eher selten so gemacht es sei denn die Klasse ist explizit dafuer entworfen.
 

123neu

Bekanntes Mitglied
Zunaechst mal bin ich kein Freund des Standard "alles private" Ansatzes, ich finde der interne Zustand der Klasse sollte Erweiterungen der Klasse zugaenglich sein, also alle Variablen eher "protected" damit einen erweiterende Klasse die Chance hat die Logik auch tatsaechlich zu erweitern
Blos nicht... damit würdest du gegen zig Anti Pattern verstoßen... Aber wenn schlechter Code das Ziel ist, gern.
 

jono

Top Contributor
Warum wurde jetzt aber "getFilme" verwendet und nicht einfach "filme" , habe die Erklärung oben überhaupt nicht verstanden.
 

thecain

Top Contributor
Weil es ein schlechtes Beispiel ist. Aber aufgrund des Namens der Klasse vermute ich nicht, dass das eine Musterlösung ist...
 

123neu

Bekanntes Mitglied
Warum wurde jetzt aber "getFilme" verwendet und nicht einfach "filme" , habe die Erklärung oben überhaupt nicht verstanden.

Es gibt dazu keine genaue Regel. Innerhalb derselben Klasse kann auf private Attribute entweder direkt oder aber über die Getter zugegriffen werden.
Wenn du ein paar Methodenaufr. einsparen möchtest, so rufe die Attribute direkt auf. Das ist dann auch übersichtlicher.
 

Robert Zenz

Top Contributor
Warum wurde jetzt aber "getFilme" verwendet und nicht einfach "filme" , habe die Erklärung oben überhaupt nicht verstanden.
Es gibt keinen Grund den ich sehen kann. Wieso einmal das Eine und einmal das Andere verwendet wurde, sehe ich nur als uneinheitlich vom Autor an. Genauso wie einmal Deutsch und einmal Englisch fuer die Namen verwendet wurde, ist ebenfalls uneinheitlich. Der Code ist einfach schlecht geschrieben, es ist ein schlechtes Beispiel.

Um etwas auszuholen was es fuer Unterschiede zwischen beiden Varainten gibt. Direkter Zugriff auf Felder ist klar:

Java:
public class Example {
    private Object field;
    
    public void doSomething() {
        field.doSomethingHere();
    }
    
    public Object getField() {
        return field;
    }

Hier ist alles klar. Aber eine ableitende Klasse hat zum Beispiel keine Moeglichkeit den Wert von "field" in der internen Logik zu veraendern. Das kann man jetzt auf zwei Arten loesen, entweder man macht das Feld "protected":

Java:
public class Example {
    protected Object field;
    
    public void doSomething() {
        field.doSomethingHere();
    }
    
    public Object getField() {
        return field;
    }

Dann kann eine ableitende Klasse den Wert kontrollieren, zum Beispiel so:

Java:
public class ExtendedExample extends Example {
    @Override
    public void doSomething() {
        field = aCompletelyDifferentValue;
        super.doSomething();
    }

Die andere Variante ist dass man den Getter ueberschreibbar haelt und und diesen dann in der internen Logik verwendet:

Java:
public class Example {
    protected Object field;
    
    public void doSomething() {
        getField().doSomethingHere();
    }
    
    public Object getField() {
        return field;
    }

Java:
public class ExtendedExample extends Example {
    @Override
    public Object getField() {
        return aCompletelyDifferentValue;
    }

Da gibt es den Unterschied.

In dem Beispiel welches du gepostet hast, gibt es aber keinen Grund weder das Eine, noch das Andere zu tun. Aber man sollte immer darauf achten dass man einheitlich ist wenn man Code schreibt, also immer nur eine Sprache fuer Namen verwenden, und immer nur einen Weg wie man auf die Felder zugreift.
 

temi

Top Contributor
Die gezeigte Klasse ist auf jeden Fall ein schlechtes Beispiel für sinnvolles OOP.

Grundsätzlich gilt: Eine Klasse sollte soviel verbergen wie möglich und nur sichtbar machen, was unbedingt nötig ist. Generell Getter und vor allem Setter für alle privaten Felder bereitzustellen, ist völliger Schwachsinn. Da kann man die Felder auch gleich öffentlich machen, das kommt auf dasselbe raus.

Mit Vererbung sollte man vorsichtig sein und Klassen entweder sehr sorgfältig für Vererbung gestalten oder Vererbung am besten gleich verbieten.
 

White_Fox

Top Contributor
Generell Getter und vor allem Setter für alle privaten Felder bereitzustellen, ist völliger Schwachsinn. Da kann man die Felder auch gleich öffentlich machen, das kommt auf dasselbe raus.
Naja, aber selbst dann hast du immernoch die Möglichkeit, Lese- und Schreibzugriffe nachträglich zu prüfen oder zu manipulieren. Wenn es mal sein muß. Das hat man nicht mehr, wenn man Felder gleich öffentlich macht.
Es mag relativ selten vorkommen, Feldzugriffe nachträglich zu bearbeiten, aber ich sehe nicht warum ich mir diese Mögilchkeit ohne Not verbauen sollte (weswegen ich ein Freund von "alles grundsätzlich private und nur Zugriffe ausschließlich über Methoden" bin).

In meinem jCLS-Projekt gab es mal eine Klasse, die einfach nur als Variablenbündel dienen sollte. Ich wollte einfach nur einen Datentyp, der einen String, eine Enumeration und noch irgendwas anderes enthält, haben. Und package private war die Klasse auch - also dachte ich, ich weiche mal von meinem strikten Vorgehen ab und habe ich das genauso hingeschlampt: einfach nur eine Klasse mit drei packageprivaten Feldern, ohne Zugriffsmethoden.

Und als es dann komplizierter wurde, hab ich es natürlich bald bereut. Das war zwar nicht die einzige Stelle, an die ich später Hand anlegen mußte, aber dieses Vorgehen hat mir trotzdem ganz erheblich viel Arbeit gemacht. Hätte ich mich mal an meinen sonstigen Plan gehalten...wenn man alles sauber macht und nur einmal schlampt kann man gewiss sein: Im Nachgang hätte man überall schlampen können, nur an dieser einen Stelle nicht.
 

temi

Top Contributor
Wenn es mal sein muß. Das hat man nicht mehr, wenn man Felder gleich öffentlich macht.
Da habe ich mich wohl falsch ausgedrückt. Der Hinweis war
Eine Klasse sollte soviel verbergen wie möglich und nur sichtbar machen, was unbedingt nötig ist.
Also Felder natürlich privat, aber kein genereller Feldzugriff über Getter/Setter zusätzlich, weil das dem entgegen steht.

Die Änderung des Zustandes einer Klasse sollte dann über Fachfunktionen passieren, nicht über das direkte Setzen von Werten, z. B. bei einem Auto über "beschleunige()" und bremse() anstatt von "setGeschwindigkeit()". Blödes Beispiel, mir fällt grad nichts besseres ein.
 

Neue Themen


Oben