Design Fehler Tabelle?

Ti9er

Grünschnabel
Hallo,

Ich Entwerfe gerade eine Tabelle die Daten Spaltenweise abspeichert (Attribute). Ein Attribut besteht aus einem Namen, Typ (eigener definierter Datentyp) und den entsprechenden Daten. Die Attribute können vom selbstdefiniertem Typ A oder B sein. Typ A speichert die Werte als String, Typ B als Double in einer ArrayList. Später soll das ganze noch um ca. 25 weiter Typen erweitert werden.

Zum Verständniss mal mein Table Interface und konkrete implementierung, mein Attribute Interface und konkrete implementierung.

Code:
// Table Interface
public interface Table extends Serializable {

    public Attribute[] getAttribute ();

    public Attribute getAttribute(int index);

    public int getColumnCount();

    public int getRowCount();

    @Override
    public String toString ();
}
Code:
public class RiskTable implements Table {

    private List<Attribute> attributes = new ArrayList<Attribute>();
    private int rowCount = 0;

    public RiskTable(List<Attribute> attributes, int rowCount) {
        addAttribute(attributes);
        this.rowCount = rowCount;
    }

    public void addAttribute(List<Attribute> newattributes) {
        for (Iterator<Attribute> iter = newattributes.iterator(); iter.hasNext();) {
            addAttribute(iter.next());
        }
    }

    public void addAttribute(Attribute a) {
        attributes.add(a);
    }

    public Attribute[] getAttribute() {
        Attribute[] x = attributes.toArray(new Attribute[0]);
        return x;
    }

    public Attribute getAttribute(int index) {
        return attributes.get(index);
    }

    public int getColumnCount() {
        return attributes.size();
    }

    public int getRowCount() {
        return rowCount;
    }
}
Code:
// Attribute Interface
public interface Attribute implements Serializable{

    public String getName();

    public void setName(String name);

    public int getType();

    public Iterator iterator();

    public void addElement(Object value);

    public void addElement(int index, Object value);

    public Object getElement(int index);

    public Object[] getElements();
    
    public void setElement(int index, Object value);

    public int size();
}
Code:
//Abstract Attribut
public abstract class AbstractAttribute implements Attribute {

    private String name;
    private int type;

    public AbstractAttribute(String name, int type) {
        this.name = name;
        this.type = type;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getType() {
        return type;
    }

}
Code:
// TypA konkret implementierung
public class TypAAttribute extends AbstractAttribute {

    private List<String> elements = new ArrayList<String>();

    public TypAAttribute(String name, List<String> elements) {
        super(name, DatenTyp.TYPA);
        for (Iterator<String> iter = elements.iterator(); iter.hasNext();) {
            addElement(iter.next());
        }
    }

    public void addElement(Object value) {
        elements.add((String) value);
    }

    public void addElement(int index, Object value) {
        elements.add(index, (String) value);
    }

    public Object getElement(int index) {
        return elements.get(index);
    }

    public Object[] getElements() {
        String[] x = elements.toArray(new String[0]);
        return x;
    }

    public void setElement(int index, Object value) {
        elements.set(index, (String) value);
    }

    public int size() {
        return elements.size();
    }

    public Iterator iterator() {
        return elements.iterator();
    }
Code:
// TypB konkret implementierung
public class TypBAttribute extends AbstractAttribute {

    private List<Integer> elements = new ArrayList<Integer>();

    public TypBAttribute(String name, List<Integer> elements) {
        super(name, DatenTyp.TYPB);
        for (Iterator<Integer> iter = elements.iterator(); iter.hasNext();) {
            addElement(iter.next());
        }
    }

    public void addElement(Object value) {
        elements.add((Integer) value);
    }

    public void addElement(int index, Object value) {
        elements.add(index, (Integer) value);
    }

    public Object getElement(int index) {
        return elements.get(index);
    }

    public Object[] getElements() {
        Integer[] x = elements.toArray(new String[0]);
        return x;
    }

    public void setElement(int index, Object value) {
        elements.set(index, (Integer) value);
    }

    public int size() {
        return elements.size();
    }

    public Iterator iterator() {
        return elements.iterator();
    }
}

Jetzt stehe ich am Punkt wo ich nicht mehr weiter weiss, bzw ich mich Frage ob ich nicht ein kompletten Denkfehler hat oder es nen eleganteren Vorschlag gibt. Wenn ich meine Daten jetzt natürlich verwenden will muss ich jetzt immer prüfen von welchem Typ sie sind und casten wegen Rückgabewert Object. Bei aktuell 2 Typen sagt man sich noch OK, aber wie erwähnt sollen es mal so 25 werden und ich müsste überall wo ich Sie verwenden will Abfragen.

Code:
RiskTable data;
        Attribute a = data.getAttribute(column);

        if(a.getType == DatenTyp.TYPA){
           String object = (String) a.getElement(row);
           ...
        }
        if(a.getType == DatenTyp.TYPB){
           double object = (Double) a.getElement(row);
           ...
        }
}

Vielen Dank schonmal an alle die sich das Anschauen. Wenn noch Fragen oder unklarheiten sind was ich meine Bitte drauf Hinweisen.

Gruß Dirk
 
Zuletzt bearbeitet:
Ich weiß nicht, für was alles du deine Daten verwenden möchtest, aber vielleicht ist es am besten, wenn du für die entsprechenden Zwecke die notwendigen Funktionen im 'Datentyp' selber implementierst. Du übergibst dann die dafür notwendigen Objekte als Parameter, und dein Daten-Objekt kümmert sich dann selber darum, Typprüfungen zu machen, seinen Wert z.B. auszugeben, mit etwas anderem zu vergleichen etc. Auf diese Weise kapselst du die Verarbeitung deines Wertes, damit nicht das umgebende Programm damit belastet wird.
 
Zurück