Здравствуйте, alex.n, Вы писали:
AN>Делаю свой контейнер, в нем есть метод AN>
AN>bool AddItemAfter<T>(T item, T anchor)
AN>
AN>При кодировании этого метода у меня возник вопрос: Куда вставить item если anchor равен null?
никуда, бросить исключение.
для вставки в начало/конец должны быть отдельные методы (prepend/append)
а вообще, если контейнер может содержать null элементы, то после какого-то null элемента.
btw, ничего не сказано может ли контейнер содержать одинаковые элементы, и куда будет вставляться если такие есть
зачем он возвращает bool тоже непонятно.
Здравствуйте, Abyx, Вы писали:
A>Здравствуйте, alex.n, Вы писали:
AN>>Делаю свой контейнер, в нем есть метод AN>>
AN>>bool AddItemAfter<T>(T item, T anchor)
AN>>
AN>>При кодировании этого метода у меня возник вопрос: Куда вставить item если anchor равен null?
A>никуда, бросить исключение. A>для вставки в начало/конец должны быть отдельные методы (prepend/append)
A>а вообще, если контейнер может содержать null элементы, то после какого-то null элемента.
null содержать не может.
A>btw, ничего не сказано может ли контейнер содержать одинаковые элементы, и куда будет вставляться если такие есть
одинаковые тоже не может содержать
A>зачем он возвращает bool тоже непонятно.
true если элемент был добавлен, иначе — false
Здравствуйте, Don Reba, Вы писали:
DR>Здравствуйте, alex.n, Вы писали:
A>>>зачем он возвращает bool тоже непонятно. AN>>true если элемент был добавлен, иначе — false
DR>Не правильнее ли в этом случае было бы назвать метод TryAddItemAfter?
Нет, т.к. false возращается если элемент в контейнере уже есть.
Здравствуйте, alex.n, Вы писали:
AN>Я не могу понять ход мыслей респондентов, которые выбрали ответ "в начало". AN>Имхо, вариант "в конец" для меня очивидный.
Я не голосовал, т.к. согласен с Abyx, но полагаю, что если в любое другое положение в последовательности можно вставить указав валидный элемент, то в начало можно вставить только если указать null. В конец можно вставив, указав последний элемент.
Здравствуйте, Don Reba, Вы писали:
DR>Здравствуйте, alex.n, Вы писали:
AN>>Я не могу понять ход мыслей респондентов, которые выбрали ответ "в начало". AN>>Имхо, вариант "в конец" для меня очивидный.
DR>Я не голосовал, т.к. согласен с Abyx, но полагаю, что если в любое другое положение в последовательности можно вставить указав валидный элемент, то в начало можно вставить только если указать null. В конец можно вставив, указав последний элемент.
ИМХО вызывать AddItemAfter, чтобы вставить элемент в начало, как-то бредово, учитывая наличие метода AddItemBefore(item, anchor).
Здравствуйте, alex.n, Вы писали:
AN>ИМХО вызывать AddItemAfter, чтобы вставить элемент в начало, как-то бредово, учитывая наличие метода AddItemBefore(item, anchor).
Вообще бредово вызывать этот метод с null. Но всё же, интуитивно, если на вопрос "после какого элемента вставить эту штуку?" отвечают "да никакого", то ожидаешь, что элемент попадёт в начало.
Ce n'est que pour vous dire ce que je vous dis.
Re: Правильно ли вы понимаете автора API?
От:
Аноним
Дата:
17.12.12 17:33
Оценка:
Здравствуйте, alex.n, Вы писали:
AN>При кодировании этого метода у меня возник вопрос: Куда вставить item если anchor равен null?
Вариант "в задницу тому, кто вызвал метод с параметром anchor равным null" принимается?
AN>Я не могу понять ход мыслей респондентов, которые выбрали ответ "в начало". AN>Имхо, вариант "в конец" для меня очивидный.
В конец это после последнего (обычно реального) элемента.
В начало это после никакого. null это и есть никакой элемент.
Эта логика очевидна в отличие от твоей очивидной
Здравствуйте, alex.n, Вы писали:
AN>Делаю свой контейнер, в нем есть метод
bool AddItemAfter<T>(T item, T anchor)
У вас метод делает сразу три вещи:
1. Ищет элемент в контейнере.
2. Вставляет другой элемент после найденного.
3. По произвольным причинам (из сигнатуры абсолютно неочевидно — по каким) код может отказаться от вставки и вернуть false.
Естественно, рано или поздно найдётся сценарий, который этот метод не покроет и придётся добавлять параметры: режим вставки, действие при добавлении дубликата, что делать если anchor не найден. Короче, как бы вы ни пытались скрыть кишки, даже если заведёте два метода (AddBefore/After) вместо перегрузок, они всё равно вылезут наружу. Api при этом нагляднее точно не станет
Чтобы не было таких монстров "можно всё, но никто не знает, как", очень рекомендую почитать FDG. Буквально на первых же страницах:
Framework Design Principle
Frameworks must be designed starting from a set of usage scenarios and code samples implementing these scenarios.
Если мы начнём с семплов — вам точно нужен будет этот метод?
MyContainer<string> someCollection = new MyContainer<string>();
someCollection.Add("Hello"); // я надеюсь, коллекция реализует ICollection<T>()?
// ...
someCollection.AddItemAfter("World", "Hello"); // Зачем в названии метода "Item"?
someCollection.AddItemAfter("!", "Hello");
foreach (string item in someCollection)
{
Console.WriteLine(item);
}
Вам очевиден результат выполнения этого кода? Очевидно, почему для добавления "world" после "hello" нужно написать "add after World, Hello"? Очевидно, что в коде баг?
Лично мне — нет. Как следствие — код отправляется в топку.
Теперь сравните ваш код с вариантом со стандартным списком:
List<string> someCollection = new List<string>();
someCollection.Add("Hello");
// ...int insertIndex = someCollection.IndexOf("Hello") + 1;
someCollection.InsertAt(insertIndex, "World");
someCollection.InsertAt(insertIndex, "!"); // Что-то тут не то;)foreach (string item in someCollection)
{
Console.WriteLine(item);
}
Если вам действительно нужен AddItemAfter — сначала напишите, как бы вы сделали ваше добавление без него. Набросайте все ожидаемые сценарии — со вставкой в начало, с учётом дубликатов, массовую вставку etc — это делается за пару минут, быстрее, чем я пишу этот пост. Посмотрите на стоимость этого кода — метод с именем Add не должен занимать O(N)
И теперь прикиньте — возможно ли вообще упаковать всё что вам нужно в один метод и насколько оно будет удобно?
И главное — никогда не спрашивайте "A или B" без приведения контекста. Проблема — не в выборе из двух вариантов. Проблема возникла раньше и привела к тому, что у вас оба варианта неюзабельны.
Вы там ничего не минируете? Тут уже написали много, а что если у вас T структура? Если не придираться к интерфейсу и обязанностям, то на null бросать исключение, а кому надо впихнуть null пусть впихивает NullObject типа T.
Дал же вашей конторе Бог девелоперов.