Kapselung Benutzerinterface für eine Liste

Leifa

Mitglied
Hallo,

ich programmiere zur Zeit ein kleines Programm und möchte es gerne "schön" programmieren, also OOP, Kapselung und Trennung von Programmlogik und GUI, damit mir das Ding nicht nach ein paar Wochen überm Kopf zusammenstürzt.

Zur Zeit beschäftigt mich diese Situation: Es gibt eine Klasse Programm mit einer Eigenschaft
Code:
private List<Person> personen = new ArrayList<Person>();
von Objekten meiner Klasse Person. Der Benutzer soll nun die Möglichkeit haben eine oder mehrere auszuwählen und soll dann seine Auswahl zurück an das Programm schicken. Wie ist nun der schönste Weg, diesen Vorgang umzusetzen? Ich habe mir mal verschieden Lösungen überlegt und würde gerne von erfahrenen Programmieren wissen, was am meisten Sinn macht.

1. Die Liste wird einfach public gemacht und ich gehe mit for(Person p: personen) die Liste durch. Beim Durchlaufen dieser Schleife lasse ich einen counter mitzählen, der sich den Index merkt. Der Nutzer wählt einige Personen aus, deren Indizes werden der Liste zum Löschen übergeben. (Problem: keine Kapselung? Die Liste sollte von außen nicht sichtbar sein.)

2. Die Liste bleibt private und es gibt eine Methode getListe(), die eine Kopie der Liste zurückgibt. Der Rest wie bei 1. (Problem: hoher Aufwand? und auch unnötige Informationen werden übergeben. Der Nutzer braucht eigentlich nur die Namen der Personen)

Auch beim Löschen von Elementen aus der Liste frage ich mich, sollten überhaupt die Indizes der gewählten Personen übergeben werden? Oder sollte das Objekt selbst übergeben werden? (ArrayList.remove macht beides möglich.)

Gibt es vielleicht noch weitere, schönere Wege?

Gruß
Leif
 
Variablen, egal ob Instanzen oder primitiv, müssen, laut OOP Konventionen, immer private sein (Außnahmen bestätigen die Regel).
Eigentlich ist der Sinn von OOP, dass es eine Klasse gibt, der gesagt wird: "Mach. Egal wie aber mach." Der Aufrufer will eigentlich nichts damit zu tun haben. Er will nur delegieren. Deshalb wäre das Zweite besser. Am Besten wäre es aber, du ließest die ArrayList in der Klasse, in der sie auch erstellt wird. Was, wenn du morgen eine LinkedList haben willst. Oder eine TreeMap? Dann musst du alles umschreiben.
 
Wenn du Anwendungslogik von deinem GUI trennen willst schau dir mal das MVC, bzw MVP Pattern an , dort delegiert / Regelt ein Controller den Ablauf zwischen dem View und der Programmlogik, es so z.B auch möglich deine Logik je nach bedarf mit verschiedenen Controllern oder Views auszustatten.
 
Zuletzt bearbeitet:
Hallo Leifa,

"korrekt" wäre es, für die Klasse, die die ArrayList beinhaltet, erst mal ein Interface anzulegen.

Java:
public interface EditPersons
{
    public boolean addPerson(Person p);
    public boolean removePerson(Person p);
    public List<Person> choosePersons(int amount);
}

Dieses Interface muss von der Klasse Programm implementiert werden.

Java:
public class Programm implements EditPersons
{
    // ...
    @Override
    public boolean addPerson(Person p)
    {
        return persons.add(p);
    }

    @Override
    public boolean removePerson(Person p)
    {
        return persons.remove(p);
    }

    @Override
    public List<Person> choosePersons(int amount)
    {
        return persons.subList(0, amount);
    }
}

Wie du siehst, geht das ganz bequem mit der Methode subList. Möchtest du, dass die Methode choosePersons etwas anderes macht, kannst du das Interface EditPersons in einer anderen Klasse implementieren und die Logik nach deinen Wünschen umsetzen, z.B. könntest du eine choosePersons-Methode implementieren, die nur jede 2. Person zurückliefert.
In der aufrufenden Klasse benötigst du eine Variable vom Typ EditPersons und kannst je nach Bedarf ein Objekt einer implementierenden Klasse erzeugen. Das ganze nennt sich Polymorphie. :rtfm:

Generell sollte man aber bei kleineren Projekten den Code nicht so sehr "over-engineeren", da oft für wenig Wirkung ein ziemlicher bloat entsteht. Aber für Übungszwecke ist es in Ordnung.

Auch beim Löschen von Elementen aus der Liste frage ich mich, sollten überhaupt die Indizes der gewählten Personen übergeben werden? Oder sollte das Objekt selbst übergeben werden? (ArrayList.remove macht beides möglich.)

Nimm einfach das simplere - du könntest in meinem Beispiel für removePerson zwei verschiedene Varianten implementieren, wobei eine zuerst den Index rausrechnet und die andere direkt über das Objekt geht und schauen was passiert 😉
 

Zurück
Oben