Frage

Angenommen, ich die folgenden Arten von Daten:

class Customer {
  String id; // unique
  OtherCustData someOtherData;
}

class Service {
  String url; // unique
  OtherServiceData someOtherData;
}

class LastConnection {
  Date date;
  OtherConnData someOtherData; // like request or response
}

Jetzt muss ich erinnere mich, wenn jeder der Kunden zu jedem der Dienste verbunden.
Ich würde die Struktur machen:

Map<Customer, Map<Service, LastConnection>> lastConnections;

Oder, um der Lage sein, durch IDs zu suchen und nicht alle gleich zu schreiben haben () und hashCode ():

Map<String, Map<String, LastConnection>> lastConnections;

Nun kann ich die LastConnection Daten zugreifen, indem

LastConnection connection = lastConnections.get(custId).get(srvUrl);

All dies scheint hässlich, vor allem, dass ich es als Parameter an zig Methoden erwarten Karte Karten von LastConnections passieren muß, so ich denke, meine eigenen Klassen zu schaffen, die so ähnlich aussehen:

class CustomerConnections extends HashMap<String, LastConnection> {
}

class AllConnections extends HashMap<String, CustomerConnections> {
    public LastConnection get(String custId, String srvUrl) {
        return get(custId).get(srvUrl);
    }
}

Ok, ich schon gelernt, dass Vererbung 3v1l ist, so wollen wir versuchen, Zusammensetzung:

class CustomerConnections {
    Map<String, LastConnection> customerConnections;
    LastConnection get(String srvUrl) { 
        return customerConnections.get(srvUrl);
    }
    ... // all other needed operations;
}

class AllConnections {
    Map<String, CustomerConnections> allConnections;
    public LastConnection get(String custId, String srvUrl) {
        return get(custId).get(srvUrl);
    }
    public CustomerConnection get(String custId) {
        return allConnections.get(custId);
    }
    ... // all other needed operations;
}

Das Problem ist, dass ich nicht sicher bin, was der beste Ansatz SOLID Prinzipien wäre und die besten Praktiken zu respektieren. Erstellen von Klassen, die nichts tun, außer erstreckt bereits Sammlungen bestehende scheint, wie Entitäten über die Notwendigen hinaus multipliziert, würde aber meinen Code deutlicher machen (vor allem, wenn es nächste Ebene ist - wie Karte von AllConnections nach Monat und so weiter). Alle mögliche Richtungen?

War es hilfreich?

Lösung

  

Erstellen von Klassen, die nichts tun   außer Verlängerung bereits bestehende   Sammlungen scheint, wie Multiplikation   Einheiten über Notwendigkeit

ich ändern würde erweitern zu verkapseln. Sie verstecken sich die Details, wie diese Informationen gespeichert sind. Clients der Klasse müssen nicht wissen, wie Sie sie mit dem Kundenanschluss Geschichte bieten. Ich denke, das ist eine gute Idee, da Sie das zugrunde liegende Modell ihren Code, ohne dass Kunden der api ändern ändern können.

  

würde aber meinen Code klarer

machen

Das ist großartig und ist ein guter Grund, dies zu tun. YourClass.getCustomerConnection (cid) ist viel klarer als yourCollection.get (id) .get (id) .getConnection (). Sie müssen das Leben der Menschen mit diesem Code leichter machen, auch wenn Sie diese Person sind.

  

(Vor allem, wenn es nächste Ebene - wie Karte von AllConnections Monat usw.)

Gut, dann voraus Sie planen und Ihren Code erweiterbar zu machen. Das ist gut OO Praxis. Meiner Meinung nach dem conculsion Sie selbst erreicht haben, ist das, was ich tun würde.

Andere Tipps

Ich würde ein spezielles Objekt zum Speichern dieser Informationen erstellen. Was Sie erstellen ein Manager Objekt, anstatt eine einfache Sammlung.

I nicht es von einer Karte oder einem anderen bekannten Sammlung Klasse ableiten lassen, da die Semantik, wie Sie diese Informationen speichern kann sich in Zukunft ändern.

Statt eine Klasse implementieren, die einen Kunden und dessen Verbindung zusammenhält, und innerhalb dieser Klasse die entsprechende Sammlung Klasse verwenden (die Sie in Freiheit sind später zu ändern, ohne die Schnittstelle und den Rest des Codes zu beeinflussen)

Ihr Kunde / Verbindungs-Manager-Klasse ist mehr als ein einfacher Behälter. Es kann Meta-Daten (zum Beispiel, wenn diese Beziehung wurde festgestellt). Es kann die Suche auf Verbindungen durchführen info bestimmten Kunden (wenn Sie benötigen). Es kann Duplikate behandeln, wie Sie benötigen, anstatt, wie die zugrunde liegende Auflistung Klasse verarbeitet sie etc. etc. Sie leicht in das Debugging / logging / Leistungsüberwachung Slot kann leicht zu verstehen, was los ist.

Ich denke, Sie sollten auch prüfen, wie die Sammlungen verwendet werden werden und wie die Daten erhalten:

  • Wenn sie einfaches Ergebnis Sets auf einer Seite (zum Beispiel) angezeigt wird, dann Standardkollektionen mit scheint vernünftig - und Sie können dann viele Standardbibliotheken verwenden, um sie zu manipulieren
  • .
  • Auf der anderen Seite, wenn sie wandelbar und alle Änderungen müssen beibehalten werden (zum Beispiel), dann sie in den eigenen Klassen Einkapselung könnte vorzuziehen sein (die dann Änderungen an Datenbanken schreiben, etc).

Wie kommen Sie und Ihre Daten bestehen bleiben? Wenn sie in einer Datenbank gespeichert ist, dann vielleicht können Sie SQL wählen LastConnections von Kunden und / oder eine Dienstleistung und / oder Monat verwenden, anstatt den Datenstrukturen selbst (und nur zurückgeben einfache Listen oder Karten von Verbindungen oder Zählungen von Verbindungen zu pflegen ). Oder vielleicht möchten Sie nicht über eine Abfrage für jede Anforderung laufen, so behalte müssen, um die gesamte Datenstruktur im Speicher.

Die Verkapselung ist in der Regel eine gute Sache, aber vor allem, wie es kann Ihnen helfen, auf den Gesetz von Demeter einzuhalten - vielleicht können Sie einige der Operationen drücken, die Sie auf die Sammlungen wieder in die AllConnections Klasse durchführen wird (was effektiv eine DAO ist). Dies kann oft Unit-Tests helfen.

Auch, warum baut HashMap hier Übel angesehen, wenn man bedenkt, dass man nur eine triviale Hilfsmethode hinzufügen? In Ihrem Code für AllConnections verhalten AllConnections wird immer auf die gleiche Art und Weise wie eine HashMap - es polymorph ersetzbar ist. Natürlich sind Sperren Sie möglicherweise in sich HashMap verwenden (statt TreeMap, etc), aber das ist wahrscheinlich, da sie die gleichen öffentlichen Methoden wie Map hat spielt keine Rolle. ob Sie tatsächlich jedoch tun, wirklich hängt davon ab, wie Sie die Sammlungen beabsichtigen wollen würde, verwenden - ich glaube einfach nicht, dass Sie automatisch Rabatt Implementierungsvererbung sollte als immer schlecht (es in der Regel nur ist ?)

class AllConnections extends HashMap<String, CustomerConnections> {
    public LastConnection get(String custId, String srvUrl) {
        return get(custId).get(srvUrl);
    }
}

Warum nicht custId+"#"+srvurl als Schlüssel in einer einfachen Map<String, LastConnection> verwenden?

oder verwenden Sie einen Tuple oder Pair-Klasse als Schlüssel, der die beiden IDs und implementiert hashCode() und equals() enthält - die " saubersten“OO-Lösung.

Warum pflegen Sie die Beziehungen zwischen den Objekten außerhalb dieser Objekte.

ich so etwas wie die folgenden würde vorschlagen:

public class Customer 
{
  public List<LastConnection> getConnectionHistory() 
  {
    ... 
  }

  public List<LastConnection> getConnectionHistory(Service service) 
  {
    ...
  }

  public List<LastConnection> getConnectionHistory(Date since) 
  {
    ...
  }
}

public class LastConnection
{
  public Date getConnectionTime() 
  {
    ...
  }

  public Service getService()
  {
    ...
  }
}

Sie dann List<Customer> an die Methoden übergeben, die diese Informationen verwenden.

Sie können eine Klasse erstellen, die Geräte Map<K,V> und intern an einen Behälter Karte übertragen:

class CustomerConnections implements Map<String,LastConnection> {
    private Map<String, LastConnection> customerConnections;

    @Override
    public LastConnection get(Object srvUrl) { 
        return customerConnections.get(srvUrl);
    }
    // all other needed operations;
}

Das Schöne an diesem Ansatz ist, dass man um einen Map passieren kann, die einen Standard hat, gut definierte Vertrag, aber Sie vermeiden Bibliotheksklassen erstreckt, die oft verpönt ist.

Bearbeiten : Wie weiter unten erwähnt, dies den Nachteil hat Sie erfordert eine Menge von Methoden zu implementieren, die auf die zugrunde liegende Sammlung von Delegierten kurz nichts tun

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top