2012-08-12 16 views
5

Mi aplicación tiene InstrumentFactory - el único lugar donde creo Instrument instancia. Cada instancia de instrumento contiene varios campos, como Ticker=MSFT y GateId=1 y también el único Id =1.Cuando necesito algún elemento, ¿debería usar su "ID int" en su lugar?

Y ahora me di cuenta de que casi nunca necesito la instancia Instrument. En el 90% de los casos solo necesito Id. Por ejemplo, ahora tengo dicho método:

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

Sabemos que no debemos pasar en los parámetros más información de la requerida. Lo que este código probablemente debería ser readaptado a:

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

90% de mi código puede ahora ser rediseñado para usar en lugar de instrumentIdInstrument.

¿Debo hacer eso? Cambiar en todas partes Instrument a instrumentId lo convertirá en un requisito difícil (cada Instrumento debe tener exactamente una identificación única). Pero, ¿qué beneficios tendré? A cambio de "requisitos duros", quiero tener algunos beneficios para eso ... (velocidad, legibilidad?) Pero no los veo.

+0

Muy buena pregunta. +1 – Mohayemin

+1

¿O tal vez GetInstrumentInfo debería ser un método en Instrument? –

+0

@Peri tiene un muy buen punto. O tal vez un comprador de propiedades sería aún mejor. –

Respuesta

4

El uso de identificadores en todas partes en lugar del objeto es un enfoque equivocado y va en contra del espíritu de OOP.

Hay dos grandes ventajas de utilizar el objeto mismo:

  1. del Es de tipo seguro. No puede pasar accidentalmente algo como Person a la primera versión, pero accidentalmente puede pasar person.Id al segundo.
  2. Hace que su código sea fácil de modificar. Si, en el futuro, decide que necesita long ids, o de alguna otra manera para identificar un único Instrument, no necesitará cambiar el código de llamada.

Y probablemente debería cambiar su diccionario también, que debería ser algo así como Dictionary<Instrument, InstrumentInfo>, no Dictionary<int, InstrumentInfo>, al igual que tiene ahora. De esta forma, obtienes las dos ventajas allí también. Para que funcione, debe implementar la igualdad en Instrument, lo que significa anular correctamente Equals() y GetHashCode() e idealmente también implementar IEquatable<Instrument>.

+0

no uso el diccionario. Yo uso matriz para la razón de rendimiento. así que accedo a él por el índice 'int'. – javapowered

+0

¿Y esas razones de rendimiento son reales? Primero debe escribir el código de limpieza y, si resulta que es demasiado lento (como lo muestra el perfil), entonces optimícelo. – svick

+0

en software HFT, debería simplemente codificar más rápido :) – javapowered

1

Siempre es mejor trabajar en términos de objetos que valores primitivos como enteros. Si mañana cambian sus requisitos y necesita algo más que la identificación, es fácil agregarlos al objeto Instrument en lugar de cambiar todo su código.

-1

Se podría sobrecargar cada función, que tenga un instrumento y una que toma un ID:

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]; 
} 

esto le dará suficiente flexibilidad para que, mientras que ir a través de cualquier lugar que llama GetInstrumentInfo para cambiarlo a pass id, el código actual seguirá funcionando.

En cuanto a si usted debe o no debe depender exclusivamente de usted. Tendría que ponderar cuánto tiempo llevaría cambiarlo frente al beneficio de realizar el cambio en el código.

+0

¿Alguna explicación para el downvote? –

1
GetInstrumentInfo(int instrumentId); 

Esto probablemente significa que el código de cliente tiene que tener un:

GetInstrumentInfo(instrument.Id); 

No permita que los usuarios de su preocupación sobre el método de pequeños detalles por el estilo. Deja que pasen el objeto completo y deja que tu método haga el trabajo.

No veo ninguna desventaja de rendimiento importante. Si pasa un Int o una referencia al objeto real.

Digamos que quería desarrollar GetInstrumentInfo un poco más, es más fácil tener acceso a todo el objeto que solo un int.

1

La primera cosa que hay que preguntarse es:

"Si tengo dos instrumentos con == ID 53, entonces ¿eso significa que son sin duda el mismo instrumento, no importa lo que o hay una? caso significativo donde podrían ser diferentes? "

Suponiendo que la respuesta es "son las mismas. Si cualquier otra propiedad difiere, es un error o porque uno de esos objetos se obtuvo después de otro, y se resolverá lo suficientemente pronto (cuando el hilo de procesamiento sea utilizando el instrumento más antiguo, deja de usarlo) "luego:

Primero, internamente, simplemente use lo que encuentre más útil. Lo más probable es que descubra que esto pasa por el int todo el tiempo, aunque obtiene algún tipo de seguridad al insistir en que se pasa un Instrument al método. Esto es especialmente cierto si toda la construcción Instrument ocurre desde un constructor internal o private al que se accede a través de métodos de fábrica, y no hay manera de que un usuario del código cree un Instrument falso con una identificación que no coincide con nada en su sistema.

Definir la igualdad como tal:

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; 
    } 
} 

Ahora, sobre todo si tenemos en cuenta que lo anterior es probable que se inline mayor parte del tiempo, no hay prácticamente ninguna diferencia aplicación en cuanto a si se utiliza la identificación o el objeto en términos de igualdad, y por lo tanto también en términos de usarlos como clave.

Ahora, se puede definir todas sus métodos públicos en cualquiera de los siguientes medios:

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

O:

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

O:

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

El impacto en el rendimiento se ser el mismo, lo que sea que elija. El código presentado a los usuarios será seguro para el tipo y garantizará que no pasen los valores falsos. La implementación elegida puede ser simplemente la que le parezca más conveniente por otros motivos.

Dado que no le costará más usar el instrumento como una llave internamente, aún así le recomendaría que haga eso (la primera de las tres opciones anteriores) como el tipo de seguridad y lo que hace difícil pasar valores falsos se aplicará también a su código interno. Si, por otro lado, encuentra que un conjunto de llamadas sigue usando el ID de todos modos (si, por ejemplo,están hablando con una capa de base de datos a la cual solo la ID significa algo), luego cambiar solo esos lugares se vuelve rápido y fácil para usted, y se oculta para el usuario.

También le brinda a sus usuarios la posibilidad de usar su objeto como clave y hacer comparaciones rápidas de igualdad, si así lo requiere.

+0

tengo InstrumentFactory que garantiza que siempre tengo solo una instancia de Instrument para cada Id. Además, Factory tiene varios métodos LookUp, como 'public Instrument Lookup (int gateId, string ticker)' – javapowered

+0

. Si hay una sola instancia garantizada globalmente, ni siquiera la necesita, ya que la igualdad predeterminada de objetos y hashcode funcionarán para tomar el ' Instrumento' como una clave. (Si los objetos son mutables, el enhebrado puede ser complicado). –

Cuestiones relacionadas