Ventajas de FindById () .
A prueba de futuro : si comenzar con Find(int)
, y luego tener que agregar otros métodos ( FindByName(string)
, FindByLegacyId(int)
, FindByCustomerId(int)
, FindByOrderId(int)
, etc), la gente como yo tienden a pasar las edades buscando FindById(int)
. No es realmente un problema si se puede y va a cambiar Find(int)
a la FindById(int)
vez que se hace necesario - el futuro es a prueba sobre estos si s.
Más fácil de leer . Find
está perfectamente bien si la llamada parece record = Find(customerId);
Sin embargo, FindById
es un poco más fácil de leer si lo es record = FindById(AFunction());
.
La consistencia . Puede aplicar constantemente el patrón FindByX(int)
/ en FindByY(int)
todas partes, pero Find(int X)
/ Find(int Y)
no es posible porque entran en conflicto.
Ventajas de Find ()
- BESO.
Find
es simple y directo, y junto operator[]
con uno de los 2 nombres de funciones más esperados en este contexto. (Algunas alternativas populares que son get
, lookup
o fetch
, dependiendo del contexto).
- Como regla general, si tiene un nombre de función que es una sola palabra conocida que describe con precisión lo que hace la función, úsela. Incluso si hay un nombre de varias palabras más largo que es un poco mejor para describir lo que hace la función. Ejemplo: longitud frente a NumberOfElements . Hay una compensación, y dónde trazar la línea está sujeto a un debate en curso.
- En general, es bueno evitar la redundancia. Si observamos
FindById(int id)
, podemos eliminar fácilmente la redundancia cambiándola a Find(int id)
, pero hay una compensación: perdemos algo de claridad.
Alternativamente, puede obtener las ventajas de ambos utilizando Ids fuertemente tipados:
CustomerRecord Find(Id<Customer> id)
// Or, depending on local coding standards
CustomerRecord Find(CustomerId id)
Implementación de Id<>
: Escribiendo valores de ID en C #
Los comentarios aquí, así como en el enlace anterior, plantearon múltiples preocupaciones con respecto a las Id<Customer>
que me gustaría abordar:
- Preocupación 1: es un abuso de genéricos.
CustomerId
y OrderID
son diferentes tipos ( customerId1 = customerId2;
=> bueno, customerId1 = orderId1;
=> malo), pero su implementación es casi idéntica, por lo que podemos implementarlos con copiar y pegar o con metaprogramación. Si bien hay un valor en una discusión sobre exponer u ocultar lo genérico, la metaprogramación es para qué sirven los genéricos.
- Preocupación 2: No detiene errores simples. Es una solución en busca de un problema. El problema principal que se elimina mediante el uso de identificadores fuertemente tipados es el orden de argumento incorrecto en una llamada a
DoSomething(int customerId, int orderId, int productId)
. Los ID fuertemente tipados también evitan otros problemas, incluido el que se le preguntó a OP.
- Preocupación 3: realmente solo oscurece el código. Es difícil saber si se retiene una identificación
int aVariable
. Es fácil decir que se retiene un ID Id<Customer> aVariable
, e incluso podemos decir que es un ID de cliente.
- Preocupación 4: estos ID no son tipos fuertes, solo envoltorios.
String
es solo una envoltura byte[]
. La envoltura, o encapsulación, no está en conflicto con la tipificación fuerte.
- Preocupación 5: está sobre diseñado. Aquí está la versión mínima, aunque recomiendo agregar
operator==
y operator!=
también, si no desea confiar exclusivamente en Equals
:
.
public struct Id<T>: {
private readonly int _value ;
public Id(int value) { _value = value; }
public static explicit operator int(Id<T> id) { return id._value; }
}
T Find<T>(string name)
o(int size)
¿cómo planea resolver los problemas inevitables?