Преимущества FindById () .
Будущее теплоизолирующие : Если начать с Find(int)
, а затем должны добавить другие методы ( FindByName(string)
, FindByLegacyId(int)
, FindByCustomerId(int)
, FindByOrderId(int)
, и т.д.), люди , как я , как правило , тратить возрастов ищут FindById(int)
. На самом деле не проблема, если вы можете и будете переходить Find(int)
к тому времени, FindById(int)
когда это станет необходимым, - будьте готовы в будущем, если s.
Легче читать . Find
отлично подходит, если вызов выглядит, record = Find(customerId);
но FindById
немного легче для чтения, если это так record = FindById(AFunction());
.
Согласованность . Вы можете последовательно применять шаблон FindByX(int)
/ FindByY(int)
везде, но Find(int X)
/ Find(int Y)
это невозможно, поскольку они конфликтуют.
Преимущества Find ()
- ПОЦЕЛУЙ.
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: Это не останавливает простые ошибки. Это решение в поисках проблемы . Главная проблема, которая устраняется с помощью строго типизированных идентификаторов, - это неправильный порядок аргументов в вызове
DoSomething(int customerId, int orderId, int productId)
. Строго набранные идентификаторы также предотвращают другие проблемы, включая тот, о котором спрашивал ОП.
- Проблема 3: Это действительно просто затеняет код. Трудно сказать, если идентификатор удерживается
int aVariable
. Легко сказать, что идентификатор удерживается 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)
как вы планируете решить неизбежные проблемы?