2012-08-12 9 views
5

Meine Anwendung hat InstrumentFactory - der einzige Ort, an dem ich Instrument Instanz erstellen. Jede Instrumenteninstanz enthält mehrere Felder, z. B. und GateId=1 und auch einmalig Id =1.Wenn ich einen Gegenstand brauche, sollte ich stattdessen seine "int id" verwenden?

Und jetzt erkannte ich, dass ich fast nie Instrument Instanz brauche. In 90% der Fälle brauche ich nur Id. Zum Beispiel habe ich jetzt eine solche Methode:

public InstrumentInfo GetInstrumentInfo(Instrument instrument) 
{ 
    return instrumentInfos[instrument.Id]; 
} 

Wir wissen, dass wir Parameter nicht mehr Informationen als erforderlich übergeben sollten. So soll dieser Code wahrscheinlich Refactoring werden:

public InstrumentInfo GetInstrumentInfo(int instrumentId) 
{ 
    return instrumentInfos[instrumentId]; 
} 

90% meines Code jetzt Refactoring werden kann instrumentId statt Instrument zu verwenden.

Soll ich das tun? Überall ändern Instrument zu instrumentId wird es als eine harte Anforderung machen (jedes Instrument sollte genau eine eindeutige ID haben). Aber welche Vorteile habe ich? Als Gegenleistung für "harte Anforderungen" möchte ich Vorteile haben ... (Geschwindigkeit, Lesbarkeit?) Aber ich sehe sie nicht.

+0

Sehr nette Frage. +1 – Mohayemin

+1

Oder vielleicht GetInstrumentInfo sollte eine Methode auf Instrument sein? –

+0

@Peri hat einen sehr guten Punkt. Oder vielleicht wäre ein Immobilien-Getter noch besser. –

Antwort

4

Die Verwendung von Ids überall anstelle des Objekts ist ein falscher Ansatz und es geht gegen den Geist von OOP.

Es gibt zwei große Vorteile bei der Verwendung des Objekts selbst:

  1. Es ist typsicher. Sie können nicht versehentlich etwas wie Person an die erste Version weitergeben, aber Sie können versehentlich person.Id an die zweite weitergeben.
  2. Es macht Ihren Code einfach zu ändern. Wenn Sie in Zukunft entscheiden, dass Sie long IDs oder eine andere Möglichkeit benötigen, um einen eindeutigen Instrument zu identifizieren, müssen Sie den aufrufenden Code nicht ändern.

Und Sie sollten wahrscheinlich Ihr Wörterbuch ändern, sollte es so etwas wie Dictionary<Instrument, InstrumentInfo>, nicht Dictionary<int, InstrumentInfo> sein, wie Sie jetzt haben. Auf diese Weise erhalten Sie beide Vorteile auch dort. Damit es funktioniert, müssen Sie die Gleichheit in Instrument implementieren, was bedeutet, Equals() und GetHashCode() und idealerweise auch IEquatable<Instrument> zu überschreiben.

+0

Ich benutze kein Wörterbuch. Ich benutze Array für Performance-Grund. Ich greife also auf den Int-Index zu. – javapowered

+0

Und sind diese Leistungsgründe real? Sie sollten zuerst sauberen Code schreiben und wenn es sich herausstellt, dass es zu langsam ist (wie durch das Profiling gezeigt), dann optimieren Sie es. – svick

+0

in HFT-Software sollten Sie nur am schnellsten Code :) – javapowered

1

Es ist immer besser, in Bezug auf Objekte als primitive Werte wie Ganzzahlen zu arbeiten. Wenn sich morgen Ihre Anforderungen ändern und Sie mehr als nur die ID benötigen, können Sie diese einfach zum Objekt Instrument hinzufügen, anstatt Ihren gesamten Code zu ändern.

-1

Sie können jede Funktion überlasten, eine, die ein Instrument und man nimmt, die eine ID nimmt:

public InstrumentInfo GetInstrumentInfo(Instrument instrument) 
{ 
    // call GetInstrumentInfo passing the id of the object 
    return GetInstrumentInfo[instrument.Id]; 
} 

public InstrumentInfo GetInstrumentInfo(int instrumentId) 
{ 
    return instrumentInfos[instrumentId]; 
} 

Dies wird Ihnen genügend Flexibilität, so dass, während Sie durch jeden Ort zu gehen, die GetInstrumentInfo nennt es zu ändern, Pass-ID, der aktuelle Code wird weiterhin funktionieren.

Ob Sie "sollte" ist nicht allein an Ihnen. Sie müssten abwägen, wie viel Zeit es braucht, um es zu ändern, im Gegensatz zu dem Vorteil, die Änderung im Code vorzunehmen.

+0

Eine Erklärung für den Downvote? –

1
GetInstrumentInfo(int instrumentId); 

Das bedeutet wahrscheinlich, dass der Client-Code eine haben muss:

GetInstrumentInfo(instrument.Id); 

nicht Sie die Benutzer Ihrer Methode Sorge um kleine Details wie das lassen. Lassen Sie sie einfach das gesamte Objekt passieren und lassen Sie Ihre Methode die Arbeit machen.

Sehen Sie keinen größeren Leistungsnachteil. Ob Sie einen Int übergeben oder auf das tatsächliche Objekt verweisen.

Nehmen wir an, Sie wollten GetInstrumentInfo ein bisschen mehr entwickeln, es ist einfacher, Zugriff auf das gesamte Objekt als nur ein Int.

1

Das erste, was Sie brauchen, um sich zu fragen, ist dies:

„Wenn ich zwei Instrumente mit ID == 53 haben, bedeutet dann, dass sie auf jeden Fall das gleiche Instrument sind, egal was Oder gibt es eine? sinnvoller Fall, wo sie anders sein könnten? "

Angenommen, die Antwort ist "sie sind beide gleich. Wenn eine andere Eigenschaft unterscheidet, das ist entweder ein Fehler oder weil ein solches Objekt nach dem anderen erhalten wurde, und das wird sich bald genug lösen (wann auch immer Thread der Verarbeitung ist Verwenden Sie das ältere Instrument, hört auf, es zu benutzen) "dann:

Zuerst, intern, verwenden Sie einfach, was Sie handier finden. Sie werden wahrscheinlich feststellen, dass dies die int die ganze Zeit zu gehen, obwohl Sie einige Typ-Sicherheit aus bestehen, dass ein Instrument an die Methode übergeben wird. Dies gilt insbesondere, wenn alle Instrument Konstruktion von einem internal oder private Konstruktor über Factory-Methoden zugegriffen wird, und es gibt keine Möglichkeit für einen Benutzer des Codes zum Erstellen eines falschen Instrument mit einer ID, die nichts in Ihrem System übereinstimmt.

definiert Gleichheit als solche:

public class Instrument : IEquatable<Instrument> 
{ 
    /* all the useful stuff you already have */ 
    public bool Equals(Instrument other) 
    { 
    return other != null && Id == other.Id; 
    } 
    public override bool Equals(object other) 
    { 
    return Equals(other as Instrument); 
    } 
    public override int GetHashCode() 
    { 
    return Id; 
    } 
} 

Nun, vor allem wenn man bedenkt, dass die oben wahrscheinlich die meiste Zeit zu inlined, gibt es so ziemlich keine Implementierung Unterschied, ob wir verwenden, um die ID oder das Objekt in Bezug auf die Gleichheit und damit auch in Bezug auf ihre Verwendung als Schlüssel.

Jetzt können Sie alle Ihre öffentlichen Methoden in einem der folgenden Mittel definieren:

public InstrumentInfo GetInstrumentInfo(Instrument instrument) 
{ 
    return instrumentInfos[instrument]; 
} 

Oder:

public InstrumentInfo GetInstrumentInfo(Instrument instrument) 
{ 
    return instrumentInfos[instrument.Id]; 
} 

Oder:

public InstrumentInfo GetInstrumentInfo(Instrument instrument) 
{ 
    return GetInstrumentInfo(instrument.Id); 
} 
private InstrumentInfo GetInstrumentInfo(int instrumentID) 
{ 
    return instrumentInfos[instrumentID] 
} 

Die Auswirkungen auf die Leistung wird sei immer gleich. Der Code, der Benutzern präsentiert wird, ist typsicher und garantiert, dass keine falschen Werte weitergegeben werden. Die gewählte Implementierung kann einfach diejenige sein, die Sie aus anderen Gründen als bequemer empfinden.

Da es Sie nicht mehr kosten wird, das Instrument selbst als Schlüssel zu verwenden, würde ich Ihnen immer noch empfehlen, dies (die erste der drei oben genannten Optionen) als Typ-Sicherheit zu tun und es schwierig zu machen falsche Werte übergeben, gilt dann auch für Ihren internen Code. Wenn Sie auf der anderen Seite feststellen, dass eine Reihe von Anrufen nur die ID trotzdem verwenden (wenn z.Sie sprechen mit einer Datenbankschicht, für die nur die ID irgendetwas bedeutet). Dann wird das Ändern dieser Orte für Sie schnell und einfach und für den Benutzer unsichtbar.

Sie geben Ihren Benutzern auch die Möglichkeit, Ihr Objekt als Schlüssel zu verwenden und schnelle Gleichheitsvergleiche zu machen, wenn es ihnen dazu passt.

+0

Ich habe InstrumentFactory, die garantiert, dass ich immer nur eine Instrument-Instanz für jede Id habe. Factory hat auch mehrere LookUp-Methoden wie 'public Instrument Lookup '(int gateId, string ticker)' – javapowered

+0

Wenn es global eine garantierte Einzelinstanz gibt, brauchen Sie das nicht einmal, da die Standard-Objektgleichheit und der Hashcode funktionieren Instrument' als Schlüssel. (Wenn die Objekte veränderbar sind, kann das Threading jedoch schwierig werden). –

Verwandte Themen