Здравствуйте, Qbit86, Вы писали:
Q>Теоретически, если игнорировать метод Reset() и интерфейс IDisposable, то в принципе интерфейс итератора вырождается до одного метода, так что интерфейс итерируемого может выглядеть лаконичнее: Q>
Q>GetIterator(): Action<Option<T>>
Q>
Ключевые слова для гугления: IEnumerator vs IObserver Push vs Pull iterators
Здравствуйте, Jack128, Вы писали:
Q>>Теоретически, если игнорировать метод Reset() и интерфейс IDisposable, то в принципе интерфейс итератора вырождается до одного метода, так что интерфейс итерируемого может выглядеть лаконичнее: Q>>
GetIterator(): Action<Option<T>>
J>Ключевые слова для гугления: IEnumerator vs IObserver Push vs Pull iterators
В моём вопросе речь идёт только про pull-итераторы посредством Action<Option<T>> вместо IEnumerator<T>.
Здравствуйте, SergeyT., Вы писали:
ST>У меня в исходном варианте даже врезка такая была. Но я решил ее не включать, поскольку NVI — это достаточно редкий паттерн в .NET-е. Я в живую не разу не видел его активного применения.
Цитата из книги Трэя Нэша "C# 2010 Ускоренный курс для профессионалов":
Шаблон NVI широко применяется в библиотеках .NET Framework, и по совершенно очевидным причинам он кочует из руководства в руководство по проектированию библиотек Microsoft.
Сам я не берусь судить, насколько это правда. Оставим на совести автора.
Там же кстати, упомянуто private virtual из C++ в контексте NVI.
Здравствуйте, Qbit86, Вы писали:
Q>Здравствуйте, Jack128, Вы писали:
Q>>>Теоретически, если игнорировать метод Reset() и интерфейс IDisposable, то в принципе интерфейс итератора вырождается до одного метода, так что интерфейс итерируемого может выглядеть лаконичнее: Q>>>
GetIterator(): Action<Option<T>>
J>>Ключевые слова для гугления: IEnumerator vs IObserver Push vs Pull iterators
Q>В моём вопросе речь идёт только про pull-итераторы посредством Action<Option<T>> вместо IEnumerator<T>.
Хм.
Еще раз посмотрел на твой интерфейс и понял, что не понял как это будет работать -)
var action = collection.GetIterator();
что я теперь должен делать с этим action'ом чтоб получить элементы коллекции ?
Здравствуйте, Jack128, Вы писали:
Q>>В моём вопросе речь идёт только про pull-итераторы посредством Action<Option<T>> вместо IEnumerator<T>. J>Еще раз посмотрел на твой интерфейс и понял, что не понял как это будет работать -) J>var action = collection.GetIterator(); J>что я теперь должен делать с этим action'ом чтоб получить элементы коллекции ?
Я ниже привёл исправленную сигнатуру, Function<> вместо Action<>. То есть итератором является возвращённое замыкание, invoke'ая которое получаем очередные элементы, завёрнутые в Option<T> (Maybe<T>). Перебираем до тех пор, пока очередной возващённый элемент не будет Option<T>.None.
Q>Я ниже привёл исправленную сигнатуру, Function<> вместо Action<>. То есть итератором является возвращённое замыкание, invoke'ая которое получаем очередные элементы, завёрнутые в Option<T> (Maybe<T>). Перебираем до тех пор, пока очередной возващённый элемент не будет Option<T>.None.
А, не заметил. Ну тогда конечно можно. Только всё равно выкидывать Dispose нельзя. Плюс нужно замену этому трюку искать.
Здравствуйте, Jack128, Вы писали:
J>А, не заметил. Ну тогда конечно можно. Только всё равно выкидывать Dispose нельзя. Плюс нужно замену этому трюку искать.
Не суть, можно интерфейс до одного метода не выхолащивать, оставить и Dispose(), и Reset(). Просто вместо пары методов MoveNext()/Current использовать один GetNext(), результат которого может как давать значение, так и являться признаком окончания. Duck typing'у не помеха.
Q>Я эту главу ещё не читал, но уже готов осуждать! Посетитель мой горячо любимый паттерн (хотя не помню, когда его использовал, и вообще скрипач не нужен), но никто не может его внятно описать.
Неплохая глава.
1) В листинге 6.4 приводится т.н. «функциональная версия паттерна „Посетитель“» ака «самописное сопоставление с образцом». Ты пишешь: «Мы можем добавить несколько перегруженных методов `Match`, которые будут принимать не все возможные типы иерархии, а лишь некоторые наиболее часто используемые». Как ты относишься к варианту передачи словаря методов вместо нескольких фиксированных списков? Сопоставление тогда вырождается в динамический поиск в ручной explicit vtable вместо статически проверяемых «свитчей»-простыней. (Пример пишу без проверки компилятором, мог что-нибудь упустить.)
void Match(IDictionary<Type, Action<LogEntry>> vtable)
{
// Lookup instead of “switch”.
Action<LogEntry> action;
if (vtable.TryGetValue(this.GetType(), out action))
{
action(this);
}
else
{
throw new InvalidOperationException("Unknown LogEntry type.");
}
}
...
void SaveLogEntry(LogEntry logEntry)
{
var vtable = new Dictionary<Type, Action<LogEntry>>
{
{ typeof(ExceptionLogEntry), SaveException },
{ typeof(SimpleLogEntry), SaveSimpleLogEntry },
}
logEntry.Match(vtable);
}
2) В листинге 6.1 в методе SaveLogEntry() что-то не в порядке с веткой `else`. Должно быть
if (simpleLogEntry != null)
SaveSimpleLogEntry(simpleLogEntry);
elsethrow new InvalidOperationException(...);
А лучше сделать метод «плоским», добавив `return`ы вместо `else`.
3) Комментарий названия паттерна от Скотта Мейерса в статье «My Most Important C++ Aha! Moments...Ever»: «Then, one day, I made a fundamental realization: the Visitor Pattern has nothing to do with visitation.»
Здравствуйте, SergeyT., Вы писали:
ST>Тот неловкий момент, когда о поступлении своей книги в продажу узнаешь с rsdn-а
Добрый день.
Читаю сейчас Вашу книгу, нравится, но есть такой вопрос-пожелание. Вы часто в тексте приводите ссылки на свои или чьи-то статьи, к которым хотелось бы позднее вернуться. Было бы очень удобно, чтобы где-нибудь, например, в Вашем блоге был полный перечень этих ссылок в том порядке, в котором они встречаются в книге. Сейчас по прочтении трети книги возвращаться и сканировать текст на наличие ссылок довольно проблематично.
Здравствуйте, breee breee, Вы писали:
BB>Читаю сейчас Вашу книгу, нравится, но есть такой вопрос-пожелание. Вы часто в тексте приводите ссылки на свои или чьи-то статьи, к которым хотелось бы позднее вернуться. Было бы очень удобно, чтобы где-нибудь, например, в Вашем блоге был полный перечень этих ссылок в том порядке, в котором они встречаются в книге. Сейчас по прочтении трети книги возвращаться и сканировать текст на наличие ссылок довольно проблематично.
В большинстве свежих книжек делается проще: заводится свой url shortener вида SergeyTeplyakovPatternsBook.com/123, где 123 — номер ссылки. И на всякий случай в конце книги, после индекса, приводится нумерованный список "номер ссылки — оригинальный адрес". Чтобы, если что, все ссылки за один приём распознать.
Здравствуйте, Qbit86, Вы писали:
Q>В мотивации не упомянута ошибка в архитектуре встроенных событий .NET, усложняющая отписку (тем самым косвенно поощряя утечки): Q>IDisposable token = subject.SomeEvent += (sender, e) => { ... };
Q>// Отписка: Q>token.Dispose(); Q>[/cs]
кошмар что творится в современном ООП... это уже всё реализовано в Delphi7 15-летней давности.
p.s. давно не занимаюсь программированием сам, но с тех пор ничего не поменялось видимо, кроме названий Free и Dispose.
Здравствуйте, VladD2, Вы писали:
VD>Зачем тогда в эту тему писать было?
Когда данный пост только появился, написать по сути книги не мог ни кто, так как книги еще не было в продаже. Тем не менее, данный пост послужил не плохой стартовой точкой обсуждения книг по паттернам и паттернов как таковых.
Здравствуйте, kaa.python, Вы писали:
KP>Когда данный пост только появился, написать по сути книги не мог ни кто, так как книги еще не было в продаже. Тем не менее, данный пост послужил не плохой стартовой точкой обсуждения книг по паттернам и паттернов как таковых.
Хочу заметить уважаемому КО, что его сообщение не только не несет смысловой нагрузки, но и является некорректным, если не сказать "оскорбительным".
Нечего сказать, проходи мимо, а не наезжай на то, что не видел. Я вот ничего не могу сказать и не говорю. Уважать надо коллег, как минимум.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Хочу заметить уважаемому КО, что его сообщение не только не несет смысловой нагрузки,
Сообщение несет смысловую нагрузку так как: 1) выражает мнение участника форума о книгах по паттернам как таковых, 2) уточняет это мнение информацией о том, что не все книги по паттернам, виденные участником форума, УГ.
VD>но и является некорректным, если не сказать "оскорбительным".
Тут КО может сделать только что-то типа этого
VD>Нечего сказать, проходи мимо, а не наезжай на то, что не видел. Я вот ничего не могу сказать и не говорю. Уважать надо коллег, как минимум.
Влад, я боюсь что после "Политики", тебе наезды уже везде мерещится начали. Если у тебя есть желание что-то мне высказать, не стесняйся, пиши: alex@sysdev.me. Ни к чему устраивать публичные разборки.
Здравствуйте, kaa.python, Вы писали:
KP>Сообщение несет смысловую нагрузку так как: 1) выражает мнение участника форума о книгах по паттернам как таковых, 2) уточняет это мнение информацией о том, что не все книги по паттернам, виденные участником форума, УГ.
Ну, можешь и дальше упираться сколько тебе угодно. Я тебе донес информацию о том, как твое сообщение выглядит со стороны.
KP>Тут КО может сделать только что-то типа этого
Оно и понятно. Хорошо ты хоть ненамеренно это делаешь.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Ну, можешь и дальше упираться сколько тебе угодно. Я тебе донес информацию о том, как твое сообщение выглядит со стороны.
Я вот из этого поста узнал про POSA.
Но неужели кто-то читал весь пятитомник?
И насчет того, что манера изложения книг по паттернам не идеальна, это верно.
Здравствуйте, Qbit86, Вы писали:
Q>>Я эту главу ещё не читал, но уже готов осуждать! Посетитель мой горячо любимый паттерн (хотя не помню, когда его использовал, и вообще скрипач не нужен), но никто не может его внятно описать.
Q>Неплохая глава.
Спасибо
Q>1) В листинге 6.4 приводится т.н. «функциональная версия паттерна „Посетитель“» ака «самописное сопоставление с образцом». Ты пишешь: «Мы можем добавить несколько перегруженных методов `Match`, которые будут принимать не все возможные типы иерархии, а лишь некоторые наиболее часто используемые». Как ты относишься к варианту передачи словаря методов вместо нескольких фиксированных списков? Сопоставление тогда вырождается в динамический поиск в ручной explicit vtable вместо статически проверяемых «свитчей»-простыней. (Пример пишу без проверки компилятором, мог что-нибудь упустить.)
Q>void SaveLogEntry(LogEntry logEntry) Q>{ Q> var vtable = new Dictionary<Type, Action<LogEntry>> Q> { Q> { typeof(ExceptionLogEntry), SaveException }, Q> { typeof(SimpleLogEntry), SaveSimpleLogEntry }, Q> } Q> logEntry.Match(vtable); Q>} Q>[/cs]
Моя идея была в том, чтобы упростить жизнь поотребителя визитора, а не его разработчика. Предложенный вариант вполне работоспособный, но сигнатура метода Match теперь уже не говорит, какие типы корректны/валидны, а какие — нет. Я заморачивался с таким pattern-matching-ом для бедных, когда у меня есть простая и стабильная иерархия и десятки мест ее использования (вот реальный пример). Добваление словаря — обобщает решение, но перекладывает ответственность на клиента. А именно этого я и хотел избежать.
Я ОК использовать такой подход в реализации метода Match, но не на стороне клиента.
Q>2) В листинге 6.1 в методе SaveLogEntry() что-то не в порядке с веткой `else`. Должно быть Q>
Q>А лучше сделать метод «плоским», добавив `return`ы вместо `else`.
Q>3) Комментарий названия паттерна от Скотта Мейерса в статье «My Most Important C++ Aha! Moments...Ever»: «Then, one day, I made a fundamental realization: the Visitor Pattern has nothing to do with visitation.»