besseres Klassenkonzept möglich?

Status
Nicht offen für weitere Antworten.

diggaa1984

Top Contributor
hallo,

ich sitz grad wieder annem thema, und frage mich wie ich das am dümmsten umsetze.

Folgende Klassen/Interfaces liegen vor:
Code:
public interface SimplePerson

public class ArrayListPerson implements SimplePerson

public class ComplexPerson extends ArrayListPerson

Inhalte:
SimplePerson stellt Methoden bereit, mit welchen es möglich ist einer Person String-Attribute zuzuordnen (Name, VName, Burzdatum, Vater, Mutter, Kinder etc.) ... alles eben Stringinfos, die durch einen Attributnamen eindeutig identifizierbar sind, und einen Wert halten. Diese werden später als Tabelle dargestellt (ALLE)

ArraListPerson setzt das ganze dann per ArrayList um, is klar.

Nun habe ich eine 3. Klasse ComplexPerson, welche zusätzliche Infos beinhaltet, wie zB Dateiliste, Fotos sonstige Sachen die nicht als Attribut auftauchen. Diese werden vorläufig nicht in der Tabelle auftauchen sondern in spezielleren Teilen der GUI (InternalFrames, andere Panel oder sonst was)

Das ganze ist nun passend wenn ich nur die ArrayListPerson als Implementierung habe.

Was passiert wenn ich irgendwann eine andere Implementierung wähle (Bsp LinkedList .. Performance steht grad nicht zur Debatte, soll nur als Bsp dienen) .. dann müsste ich die ComplexPerson dahingehend ja anpassen (extends umbaun) ... eine neue ComplexPerson-Klasse ist nicht nötig, da der Code in dieser unabhängig von den Attributen der Oberklasse ist.

gibt es eine Möglichkeit eine ComplexPerson zu coden, und auf elegantere Weise diese Oberklassenäbhängigkeit ins Spiel zu bringen?

mit Generics würde ich dafür sorgen das ich ein SimplePerson-Objekt in der ComplexPerson drin hab, das würde ich eigentlich vermeiden wollen, in der Nutzung gefällt mir die Vererbung besser.

war das irgendwie verständlich? :D
 
G

Gast

Gast
Hi,
erstmal vorab, warum Du verschiedene Daten in einer ArrayList abspeicherst ist mir nicht ganz klar, aber da hast Du sicherlich einen Grund?
Vielleicht solltest Du mal über eigene Variablen für die unterschiedlichen Attribute nachdenken oder z.B eine Map verwenden.

Ansonsten besteht Dein Problem worin genau? Du hast ein Interface, welches die konkreten MEthoden definiert, die jede Person anbietet. Dazu hast Du eine (austauschbare) Implementierung. Die realisiert (soweit ich das verstanden habe) genau das, was im Interface deklariert wurde. Zudem hast Du die Klasse ComplexPerson, welche nun weitere Eigenschaften hinzufügt.
Alles worin Dein Problem besteht lässt sich durch genaueres hinschauen lösen. Ich würde Dir fast unterstellen, dass Du die Konzepte von Vererbung und der Verwendung von Interfaces noch nicht ausreichend verstanden hast. Deshalb ein ernstgemeinter Rat, schau Dir die nochmal gut an, die machen in Java einiges aus (an Komfort und Einfachheit!).

An sich kannst Du Deine ArrayListPerson als ein SimplePerson-Interface betrachten. Alles was im Interface "zugesichert" wird (die öffentlichen Methoden) findest Du in ArrayListPerson. Umgekehrt gilt das natürlich nicht! Ist jetzt ComplexPerson spezieller als ArrayListPerson, dann ist es auch eine SimplePerson Realisierung, da die vorhandenen Methoden (und damit die Implementierung des Interface) erhalten bleibt.

Und nun ja, man sieht es schon, was Du eigentlich möchtest ist die konkrete Implementierung (ArrayListPerson) gegen eine andere auszutauschen. Was haben alle möglichen Implementierungen gemeinsam? Richtig, das sie das Interface SimplePerson implementieren. Also ist alles was Du brauchst die Möglichkeit
 

Landei

Top Contributor
Vererbung ist eine "ist ein" Beziehung. Ist eine ArrayListPerson eine SimplePerson? Das ist etwa so, als würdest du sagen, ein Ameisenhügel ist eine spezielle Art Ameise. Was spricht gegen ArrayList<SimplePerson> und ArrayList<ComplexPerson>? Wenn du an den Listen spezielle Funktionalität brauchst, kannst du sowas machen:
Code:
abstract class PersonList<T extends SimplePerson> extends ArrayList<T> {
...
}
class ArraySimplePersonList extends PersonList<SimplePerson> {
...
}
class ArrayComplexPersonList extends PersonList<ComplexePerson> {
...
}
Aber das ist nur ein Beispiel, da gib es -zig Möglichkeiten. Hauptsache, du vergisst ganz schnell die Idee, eine Liste von X von der Klasse X abzuleiten.
 

diggaa1984

Top Contributor
aeh das ArrayListPerson bezieht sich darauf, das ich die Attribute und Werte .. also die String-Infos zur Person in ArrayListen ablege, das hat nix mit List<Person> zu tun.

Code:
public interface SimplePerson {

void addEntry(String e);
void addEntry(String e, String vall);
void clear();
void deleteEntry(String e);
void editEntry(String e, String val);
List<String> getData();

}

das is das Interface. ArrayListPerson speichert nun Attribute und Werte der Einträge mit Hilfe einer ArrayList.

Und Ziel der ComplexPerson war es, diese normalen StringInfos durch speziellere Infos zu erweitern, je nachdem was ich in dem Programm noch darstellen möchte (das kann man quasi später beliebig erweiter .. nur über diese ComplexPerson-Klasse) .. Die String-Infos sind ja auch in dem Sinne durch die Basis der List-Klassen-Nutzung auch beliebig erweiterbar, aber alles was da rein kommt soll in einer Tabelle dargestellt werden, das will ich mit Fotos und dergleichen nicht, daher die Abkopplung der komplexen Attribute sogesehen.

Mir gehts nich darum irgendwelche ListenImplementierungen zu schreiben.

und was ich vermeiden wollte war folgendes:
Code:
ComplexPerson<SimplePerson> p = new ComplexPerson<ArrayListPerson>();
p.getSimplePerson().addEntry("bla","blu");
p.getSimplePerson().editEntry("bla","foo");
p.getsimplePerson().clear(); //sollte klar sein was ich meine

//dann lieber
ComplexPerson p = new ComplexPerson(); //aber hier fehlt mir eben die Wahl der Implementierung ;/
p.addEntry("bla");

erstmal vorab, warum Du verschiedene Daten in einer ArrayList abspeicherst ist mir nicht ganz klar, aber da hast Du sicherlich einen Grund?

was meinst damit? nen JTableModel speicher auch verschiedene Daten in Vectoren .. was bitte is der Unterschied zu meinen Daten? Ich glaub das hast mich falsch verstanden, es sind alles String-Infos ... du glaubst nich im Ernst, dass ich für Name, VName, Zuname, DatumX, DatumY, Kinder, VaterName, Muttername und weiss der Geier was, alles extra Variablen anlege? da schränke ich den Nutzer massiv ein bezüglich der möglichen Attribute die er speichern kann, das soll er doch bitte selbst entscheiden können (Tabelle kann quasi von ihm erweitert werden).

An sich kannst Du Deine ArrayListPerson als ein SimplePerson-Interface betrachten. Alles was im Interface "zugesichert" wird (die öffentlichen Methoden) findest Du in ArrayListPerson

Ist doch der Sinn der Implementierung von einem Interface !?

Umgekehrt gilt das natürlich nicht! Ist jetzt ComplexPerson spezieller als ArrayListPerson, dann ist es auch eine SimplePerson Realisierung, da die vorhandenen Methoden (und damit die Implementierung des Interface) erhalten bleibt

auch das ist mir bewusst, das wäre der Teil der mir aber meiner Wunschlösung am nächsten kommt, nämlich obiger Nutzung. Das ich die Methoden in ArrayList nicht in Complex-Person reinnehme hat eben den Grund darin, das ich diese simplen attribute von den komplexeren trennen möchte (eine wird in tabelle dargestellt, der rest irgendwie aber nicht in der tabelle, das können JTrees, Images oder sonst was sein, das wollt ich daher schon trennen)
 

Marco13

Top Contributor
:autsch: Hähm? ???:L

Also, FALLS ich das jetzt richtig verstanden habe, dann hast du sowas
Code:
interface SimplePerson
{
    void addEntry(String a, String b;
}

class ArrayListPerson implements SimplePerson
{
    private ArrayList list; 

    void addEntry(String a, String b) { list.add(a); list.add(b); } // oder so
}

class ComplexPerson extends ArrayListPerson
{
    private Data data;

    void setComplexData(Data d) { this.data = d; } // oder so
}

Und jetzt geht es darum, dass die Abhängigkeit von ComplexPerson und ArrayListPerson unerwünscht ist?

FALLS ich das jetzt richtig verstanden habe, könntest du vielleicht ein weiteres Interface einführen - dann hast du wieder freie Wahl bei der Implementierung
Code:
interface SimplePerson
{
    void addEntry(String a, String b;
}

interface ComplexPerson extends SimplePerson
{
    void setComplexData(Data d);
}

class ArrayListPerson implements ComplexPerson
{
    private ArrayList list; 

    void addEntry(String a, String b) { list.add(a); list.add(b); } // oder so
}

class ComplexArrayListPerson extends ArrayListPerson implements ComplexPerson
{
    private Data data;

    void setComplexData(Data d) { this.data = d; } // oder so
}
(oder so)

(Irgendwie klingt das alles ziemlich strange: WAS gibt es denn? Personen und ComplexPersonen - also dafür jeweils ein Interface und eine Default-Implementierung ...?)
 

diggaa1984

Top Contributor
für ComplexPerson würde ich kein interface brauchen, die Implementierung davon muss nicht austauschbar sein. Daher wäre nur eine Klasse nötig, welche diese komplexen Attribute umsetzt.

Die simplen Daten können in der Vorstellung schon eher einfach durch eine andere Implementierung ersetzt werden, da es sich da nur um Strings handelt, welche eben in bestimmten Datenstrukturen (je nach Implementierung) liegen.

Ich könnte selbstverständlich auch alles aus ComplexPerson in der Implementierung der SimplePerson reinschreiben, habe aber dann das Problem, das ich bei Wahl einer anderen Implementierung dieses interfaces die Methoden, welche aus ComplexPerson stammen, redundant vorliegen hätte, das is natürlich genauso unnötig wie gewollt.

also:

interface simplePerson
ArrayListPerson implements simplePerson (eine mögliche Implementierung, Ablage der Strings in ArrayListen)
ComplexPerson (Methoden nur 1x nötig und unabhängig von der gewählten Implementierung des Interfaces)

Wichtig ist mir eben das ich den Code in der ComplexPerson nicht doppelt rumliegen hab. Aber wie mir scheint kann ich das alles nur wie folgt lösen, obwohl es mir nicht 100% zusagt:

Code:
public class ComplexPerson {

    private SimplePerson person = null;

    public ComplexPerson() {
        person = new ArrayListPerson();
    }

    public SimplePerson getPersonRef() {
        return person;
    }
}

nicht das gelbe vom Ei, oder gibts es eine Möglichkeit durch Generics wo ich aber festlege, dass der übergebene Typ SimplePerson implementieren muss?!

dann könnte ich ausserhalb der ComplexPerson sagen welche implementierung von SimplePerson zugrunde liegen soll .. aber ich seh immer nur <T extends ...> .. geht das auf interfaces?

Ausserdem wäre es möglich einfach nur die Implementierung zu nutzen und die komplexen Attribute in ComplexPerson einfach auszublenden, wenn ich nicht über diese ComplexPerson-klasse gehe. Quasi hab ich da ja auch mehr Spielraum
 

Marco13

Top Contributor
Das letzte, was du gepostet hast, ist schon FAST das, was ich jetzt (wo ich es IMMERnoch nicht 100% verstanden habe) als nächste Option in den Raum gestellt hätte: Das "Decorator"- oder "Delegate"-Pattern:
Code:
public class ComplexPerson implements SimplePerson 
{
    private SimplePerson person = null;

    public ComplexPerson() {
        person = new ArrayListPerson();
    }

    // ALLE Methoden aus dem "SimplePerson"-Interface werden einfach an 'person' weitergereicht
    // Die Implementierung von 'person' wird dann durch EINE Zeile (im Konstruktor) festgelegt
    void addEntry(String a, String b)
    {
        person.addEntry(a,b);
    }
}
.... KÖNNTE das was sein, was du ... meinst....?
 

diggaa1984

Top Contributor
uff .. das gibt mir die Möglichkeit der Nutzung die ich präferiere (kein complex.getsimple().addEntry() nutzen zu müssen) ... die Wahl der Implementierung fällt hierbei aber immer noch in die ComplexKlasse ... nuja ich werd es dann wohl so machen, obwohl es aber bestimmt nicht schön ist das einfach so durchzuleiten (also ist ja overhead) oder?

nuja, vielleicht ein komisches Problem :D ... dekorieren triffts im übertragenen sinne ja schon etwas ... ich stell der Person durch diese kompexe klasse ja weitere attribute zur verfügung.
 

Marco13

Top Contributor
die Wahl der Implementierung fällt hierbei aber immer noch in die ComplexKlasse

Das kann man ändern, indem an die gewünschte Implementierung (oder eine PersonFactory) im Konstruktor übergibt, oder sonstwie.... irgendwo MUSS die Implementierung ja "bekannt" sein :wink:

... nuja ich werd es dann wohl so machen, obwohl es aber bestimmt nicht schön ist das einfach so durchzuleiten (also ist ja overhead) oder?

nuja, vielleicht ein komisches Problem :D ... dekorieren triffts im übertragenen sinne ja schon etwas ... ich stell der Person durch diese kompexe klasse ja weitere attribute zur verfügung.


Deswegen ja die Stichworte. Das "Weiterleiten" ist eigentlich das Delegation-Pattern http://en.wikipedia.org/wiki/Delegation_pattern#Simple_Java_example , aber in diesem speziellen Zusammenhang (d.h. sinngemäß: wenn der Delegierende das gleiche Interface erfüllt) nennt man es eher Decorator: http://de.wikipedia.org/wiki/Decorator#Beispiele
 

diggaa1984

Top Contributor
ah fetzt ... also ich werd dann wohl PersonFactory und Decorator nutzen .. dann ist ja quasi genau das erreicht was ich wollte .. hoff ich :D

Wahl der Implementierung ausserhalb der ComplexKlasse und angesprochene Nutzung der Klasse ohne erst mit getSimple() zu arbeiten ... hm juuuut .. danke für die Tipps :D

werd ich mich mal rumschlagen mit den Pattern
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
R Besseres Programmierdesign Allgemeine Java-Themen 2
berserkerdq2 SceneBuilder GUI erstellt, nun muss ich noch ein Polygon erstellen, ist die Connection möglich? Allgemeine Java-Themen 3
E Es ist nicht möglich, eine Batch-Anweisung auszuführen. Allgemeine Java-Themen 9
B Arrays von Methoden möglich? Allgemeine Java-Themen 44
D VBA Code mit Java ausführen möglich? Allgemeine Java-Themen 10
R Java Stream: Ist es möglich, einen stream zusammenzufassen Allgemeine Java-Themen 6
M WSDL: Doppelte Typenames (Keine Verwendung möglich) Allgemeine Java-Themen 5
M Keine weitere Eingabe in der Main möglich. Eventueller Ansatz über while. Allgemeine Java-Themen 8
I Eine Anwendung so gut wie möglich beschützen Allgemeine Java-Themen 9
D Java auf Webserver Website möglich Allgemeine Java-Themen 7
I PrinterJob - bestimmtes Druckerfach festlegen möglich? Allgemeine Java-Themen 2
D Eine Forschleife mit Threads abarbeiten um es zu schneller zu machen. Ist das möglich? Allgemeine Java-Themen 20
OnDemand Zeilenumbruch ignorieren möglich? Allgemeine Java-Themen 1
0 Eingabe nicht möglich... Allgemeine Java-Themen 12
FunnyO KeyEvent.VK_ + int i, ausgeben mit Bot möglich? Allgemeine Java-Themen 2
C Programmierung von Fotoeffekten mit Java möglich? Allgemeine Java-Themen 3
B ist es möglich in java keyboardtöne per MIDI kabel aufzunhemen ? Allgemeine Java-Themen 5
F Mehrfachverebung in Java (möglich)? Allgemeine Java-Themen 4
F E-Mail aus JAVA senden nach Umstellung auf Netbean 7.4 mit Java 7U45 nicht mehr möglich Allgemeine Java-Themen 4
E Ermitteln einer eindeutigen ID eines Objekts möglich? Allgemeine Java-Themen 17
R Löschen von Files nicht möglich Allgemeine Java-Themen 11
F Frage zu Regex möglich Allgemeine Java-Themen 4
P Code in Methode auslagern möglich? Allgemeine Java-Themen 9
P Datentypen float mit komma statt punkt möglich? Allgemeine Java-Themen 6
DStrohma Swing Nicht möglich für ein JPanel den Fokus zu bekommen? Allgemeine Java-Themen 9
H JTable per iText in PDF: Größenanpassung möglich? Allgemeine Java-Themen 2
GianaSisters Erste Schritte Debuggen im CMD möglich ? Allgemeine Java-Themen 19
C Strings und JSON Objekte so klein wie möglich im Speicher ablegen Allgemeine Java-Themen 5
P RegEx mit HTML Parser für Java möglich? Allgemeine Java-Themen 10
F Screenshot von gewissen Anwendungen nicht möglich Allgemeine Java-Themen 5
K Serialisierung in Properties-Datei möglich? Allgemeine Java-Themen 3
Haave Audio Device Unavailable: Kein gleichzeitiger Zugriff auf Soundsystem möglich Allgemeine Java-Themen 7
B Arraylist.contains(Klasse) möglich? Allgemeine Java-Themen 19
J Objekt selbst ertellen möglich? Allgemeine Java-Themen 6
J DLL ansteuern möglich? Allgemeine Java-Themen 3
D Double to Integer - ist das möglich? Allgemeine Java-Themen 3
U Externe Logiken möglich? Allgemeine Java-Themen 8
K Test-Code in Java-Klassen verstecken (wie mit Precompiler möglich) Allgemeine Java-Themen 10
S Klassenverfolgung möglich? Allgemeine Java-Themen 18
T Zugriff per Reflection o.ä. möglich? Allgemeine Java-Themen 18
D JOptionPane nur 1 Input möglich? Allgemeine Java-Themen 6
N Werte Von C++ nach Java über den Stream möglich? Allgemeine Java-Themen 8
J Immutable mit Interfaces möglich? Allgemeine Java-Themen 2
F Code vereinfachen möglich? Allgemeine Java-Themen 18
E Attribute in Interfaces möglich? Allgemeine Java-Themen 17
B Chat öffnen nicht möglich ! Allgemeine Java-Themen 5
L Kein Ausführen möglich Allgemeine Java-Themen 3
S Datei aller möglich encodings generieren Allgemeine Java-Themen 2
P Ist das möglich mit Java - wenn Nein wie sonst? Allgemeine Java-Themen 8
M ist "public abstract class * extends" möglich? Allgemeine Java-Themen 2
S drucken unter j2sdk-1.4 möglich; unter jdk1.5 nicht; warum? Allgemeine Java-Themen 4
M 2 verschiedene LookAndFeels in einem Fenster möglich? Allgemeine Java-Themen 6
P Dynamisch casten - möglich? wie? Allgemeine Java-Themen 5
F POI Library - Graphic in Excel inserten möglich? Allgemeine Java-Themen 2
H Vererbung auch ohne erzeugung einer Instanz möglich? Allgemeine Java-Themen 3
N Graphische Oberfläche dynamisch erweitern möglich? Allgemeine Java-Themen 4
D Buffer Overflow in Java möglich? Allgemeine Java-Themen 5
G Java-1.5 mit Eclipse möglich? Allgemeine Java-Themen 26
B Java-Programm auf Handheld (Windows CE) möglich? Allgemeine Java-Themen 2

Ähnliche Java Themen

Neue Themen


Oben