Переваги FindById () .
Майбутнє теплоізолюючі : Якщо почати з Find(int)
, а потім повинні додати інші методи ( FindByName(string)
, FindByLegacyId(int)
, FindByCustomerId(int)
, FindByOrderId(int)
, і т.д.), люди , як я , як правило , витрачати віків шукають FindById(int)
. Не дійсно проблема , якщо ви можете і буде змінюватися , Find(int)
щоб , FindById(int)
як тільки це стане необхідним - майбутнє коректури про них , якщо с.
Легше читати . Find
ідеально добре, якщо дзвінок виглядає, що record = Find(customerId);
все-таки FindById
трохи легше для читання, якщо він є record = FindById(AFunction());
.
Послідовність . Ви можете послідовно застосовувати FindByX(int)
/ FindByY(int)
шаблони скрізь, але Find(int X)
/ Find(int Y)
це неможливо, оскільки вони суперечать.
Переваги Find ()
- KISS.
Find
є простим і простим, і поряд з operator[]
цим є одним із 2 найочікуваніших імен функцій у цьому контексті. (Деякі популярні варіанти того get
, lookup
чи fetch
, в залежності від контексту).
- Як правило, якщо у вас є назва функції, це єдине відоме слово, яке точно описує, що функція виконує, використовуйте її. Навіть якщо є довше багатословне ім'я, яке трохи краще описує те, що робить функція. Приклад: Довжина проти NumberOfElements . Існує компроміс, і де провести межу, є предметом постійної дискусії.
- Як правило, добре уникати надмірностей. Якщо ми подивимось
FindById(int id)
, ми можемо легко усунути надмірність, змінивши його на Find(int id)
, але є торгівля - ми втрачаємо деяку чіткість.
Ви також можете отримати переваги обох за допомогою сильно набраних ідентифікаторів:
CustomerRecord Find(Id<Customer> id)
// Or, depending on local coding standards
CustomerRecord Find(CustomerId id)
Реалізація Id<>
: Сильно вводити значення ідентифікаторів у C #
Коментарі тут, як і посилання вище, викликали численні занепокоєння щодо Id<Customer>
того, про що я хотів би звернутися:
- Концерн 1: Це зловживання дженериками.
CustomerId
і OrderID
різні типи ( customerId1 = customerId2;
=> хороший, customerId1 = orderId1;
=> поганий), але їх реалізація майже однакова, тому ми можемо реалізувати їх або за допомогою копіювальної пасти, або за допомогою метапрограмування. Незважаючи на те, що в дискусії про викриття або приховування загального значення існує цінність, метапрограмування - це те, для чого потрібні дженерики.
- Концерн 2: Це не зупиняє прості mistakes./It's рішення в пошуках проблеми Основне питання , який видаляється за допомогою сильно типізованих Ідентифікатори неправильний порядок аргументів у виклику
DoSomething(int customerId, int orderId, int productId)
. Сильно набрані ідентифікатори також запобігають іншим проблемам, включаючи ту, про яку було задано ОП.
- Занепокоєння 3: Це дійсно просто затьмарює код. Важко сказати, чи зберігається ідентифікатор
int aVariable
. Неважко сказати, що Id зберігається Id<Customer> aVariable
, і ми навіть можемо сказати, що це ідентифікатор клієнта.
- Концерн 4: Ці ідентифікатори не є сильними типами, а лише обгортками.
String
це просто обгортка навколо byte[]
. Обгортання або інкапсуляція не суперечить сильному набору тексту.
- Побоювання 5: Це сконструйовано. Ось мінімальна версія, хоча я рекомендую додавати
operator==
і operator!=
, якщо ви не хочете покладатися виключно на 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)
або(int size)
як плануєте вирішити неминучі проблеми?