Re[7]: паттерны экслюзивно для .net c#
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 27.03.14 11:48
Оценка: 20 (1)
Здравствуйте, Sinix, Вы писали:

I>>Это GOF-паттерны в пересказе от XopoSHiy. Рассуждения применимы исключительно к GOF и ни к чему более, а между тем паттерны есть вообще везде.

S>Тогда паттерны у тебя вырождаются в баззворд, который не несёт никакой нагрузки.

Наоборот. Если ты не заметил, то паттерны GOF уже давно превратились в баззворды безо всякого смысла. За упоминание паттернов скоро лицо будут бить.

>Т.к. он может обозначать и типовые проблемы, как в GoF/Фаулере, и инструмент для решения проблем (как у Nuseraro), и рекомендации по проектированию API (как в FDG).


Я бы не ставил паттерны GOF вместе с паттернами у Файлера. Фаулер с Кентом Беком частенько стебутся с GOF.

S>Если в таком ключе обсуждать, у нас вообще дикая путаница выйдет.


Путаница уже давно и именно из за подхода GOF.

I>>На самом деле типовую проблему можно решить десятком разных способов и каждое решение будет типовым. С тз GOF не ясно, не то один паттерн, не то десять разных.

S>По-моему (тут я согласен с XopoSHiy), неясность возникает если читать GoF как готовый решебник.

А он и есть решебник. При чем решение дается сходу, там где Intent, и там где диаграма. А проблема ставится неявно в простынях текста и кода.

Вот state

"Allow an object to alter its behavior when its internal state changes. The object will appear to change its class"


Это решение в чистом виде. Теперь посмотри Джошуа Кериевски, чего он пишет про State.

Вот strategy

"Define a family of algorithms, encapsulate each one, and make them interchangeable.
Strategy lets the algorithm vary independently from clients that use it. "


И снова — решение в чистом виде.

Decorator

Attach additional responsibilities to an object dynamically. Decorators provide
a flexible alternative to subclassing for extending functionality


Опаньки — и здесь решение.

>А если смотреть на описание проблемы (кстати это первый пункт в описании каждого паттерна), то становится понятно, что неоднозначность не в самой книжке, а в том, с какой стороны мы смортрим на проблему.


В GOF описание проблемы подается невнятно, многословно и на конкретных примерах. Описание паттерна это сходу решение, еще до постановки проблемы.

I>>ВОт берем например книгу Фаулера про DSL и видим, что один и тот же пример идет почти через всю книгу. Опаньки, сразу ясно, что надо выбирать тот, который лучше подходит в конкретной ситуации.

S>Не читал но осуждаю, судя по оглавлению и превью — там вообще про классические паттерны речь не идёт, один-в-один пересказ dragon book с упором на особенности DSL.

Нет никаких "классических" паттернов. Все паттерны относятся к конкретным областям. Это может быть и кодирование, и АПИ, и внутренний дизайн и архитектура и все что угодно.

DSL это не пересказ dragon book, это навроде антологии вычислительных моделей. Из книги дракона только одна или две главы.
Re[8]: паттерны экслюзивно для .net c#
От: Sinix  
Дата: 27.03.14 12:05
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Наоборот. Если ты не заметил, то паттерны GOF уже давно превратились в баззворды безо всякого смысла. За упоминание паттернов скоро лицо будут бить.

И XopoSHiy как раз привёл логичное обоснование, почему оно так вышло. Не, конечно остаётся ещё версия "GoF изначально является бесполезной фигнёй, раскрученной на волне хайпа", но тогда и обсуждать нечего. Фигня — она и есть фигня

I>А он и есть решебник. При чем решение дается сходу, там где Intent, и там где диаграма. А проблема ставится неявно в простынях текста и кода.

I>В GOF описание проблемы подается невнятно, многословно и на конкретных примерах. Описание паттерна это сходу решение, еще до постановки проблемы.
Тут согласен. С такой точки зрения я неправ и разницы действительно никакой.

I>DSL это не пересказ dragon book, это навроде антологии вычислительных моделей. Из книги дракона только одна или две главы.

Ок, спасиб!
Re[4]: паттерны экслюзивно для .net c#
От: -n1l-  
Дата: 27.03.14 16:29
Оценка:
Может я сути не понял, но я выложил справочник которым пользовался для того, что бы быстро въехать в тему по определенному шаблону проектирования.
Это не мое автороство. Но знаю точно, что много скопипастено с вики.
Re[7]: паттерны экслюзивно для .net c#
От: Nuseraro Россия  
Дата: 28.03.14 03:54
Оценка:
S>Неа, тут та же путаница: рефакторинг — это общее описание проблемы ("фиговый код, нужно улучшить"). Замена стратегии на Func/Action — это конкрентый инструмент.

Но эту проблему можно решить самыми различными способами: дописать комментариев, написать внешнюю документацию, переписать код.

Рефакторинг — проблема тяжелого к редактированию/поддержке кода + решение в виде улучшение его внутренней структуры. Вот и Фаулер пишет:

Рефакторинг представляет собой процесс такого изменения программной системы, при котором не
меняется внешнее поведение кода, но улучшается его внутренняя структура.

Можно говорить о том, что понимание проблемы важнее, а главное, первичнее, специфичного решения, но неправильно говорить, что решение вообще не важно.
Homo Guglens
Re[8]: паттерны экслюзивно для .net c#
От: Sinix  
Дата: 28.03.14 05:09
Оценка: +1
Здравствуйте, Nuseraro, Вы писали:

S>>Неа, тут та же путаница: рефакторинг — это общее описание проблемы ("фиговый код, нужно улучшить"). Замена стратегии на Func/Action — это конкрентый инструмент.


N>Можно говорить о том, что понимание проблемы важнее, а главное, первичнее, специфичного решения, но неправильно говорить, что решение вообще не важно.

Решение приведённое в качестве примеров — вообще не важно. Зачастую там фигня полная.

Выше -n1l- дал ссылку на шпаргалку по паттернам в творческом переложении под c#. Там как раз почти каждая реализация — пример как делать не надо.
Например, паттерн builder:
abstract class Builder
{
  public virtual void BuildPartA()
  {
  }
  public virtual void BuildPartB()
  {
  }
  public virtual Product GetResult()
  {
  }
}


А теперь смотрим на реальные сценарии использования и понимаем, что реализацию ваяли от балды. Даже если отбросить лютый изврат в виде "class Director ...":

Во-первых: решаемая задача у нас — упрощение создания сложного объекта, а не возможность подмены реализации. В примере делается упор на второй пункт, первый не иллюстрируется вообще.

Во-вторых, смотрим на реальные билдеры из фреймворка.
Если билдер должен только заполнять свойства — то у билдера свойства и должны быть, а сам билдер заполняется через object initializer, см на ProcessStartInfo или на SqlConnectionStringBuilder.
Если использование билдера предполагает цепочку вызовов вида
 var result = builder
  .BuildPartA()
  .BuildPartB()
  .GetResult();

— должен быть fluent api, и, как следствие, виртуальные методы должны быть protected, а public api должно возвращать точный тип билдера.

В-третьих, не рассмотрены типовые проблемы при реализации билдера — случай, когда тип результата зависит от настройки билдера, валидацию параметров, способы избежать отслеживания состояния в билдере и т.д. и т.п.


Так что да, решение которое обычно приводится как иллюстрация, вообще не важно.
Re[9]: паттерны экслюзивно для .net c#
От: Nuseraro Россия  
Дата: 28.03.14 05:43
Оценка:
Хе-хе вижу мы разговариваем на одном языке, но называем одними словами разные вещи. Без большого желания понять друг друга пользы мы не получим
Homo Guglens
Re[10]: паттерны экслюзивно для .net c#
От: Sinix  
Дата: 28.03.14 06:21
Оценка:
Здравствуйте, Nuseraro, Вы писали:

N>Хе-хе вижу мы разговариваем на одном языке, но называем одними словами разные вещи. Без большого желания понять друг друга пользы мы не получим


Ну, речь у нас о паттернах, поэтому я стараюсь придерживаться классики — терминологии из GoF

Тут постоянно по ветке путаются практически применимые решения, как топикстартер просил, эксклюзивно для шарпа и "решения" в стиле

решение в виде улучшения его внутренней структуры

aka

- Сова, расскажи — а как нам стать ежиками?
— Мое дело — стратегия!



Поэтому и путаница.

FDG-Рихтер и прочая суровая матчасть рассказывает в основном про решение проблем на практике. Фаулер, GoF, Кен etc — "про стратегию". Конечно, можно утверждать что разницы никакой, но тогда и смысла в обсуждении вообще никакого.
Re[7]: паттерны экслюзивно для .net c#
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 28.03.14 06:46
Оценка: +3
Здравствуйте, Sinix, Вы писали:

S>Неа, тут та же путаница: рефакторинг — это общее описание проблемы ("фиговый код, нужно улучшить"). Замена стратегии на Func/Action — это конкрентый инструмент.


Рефакторинг это не описание проблемы, это просто безопасные преобразования кода. Дело не в улучшении, а в изменении текущей структуры кода. А вот для чего это может понадобиться — для улучшения, для изучения, для исследования и тд — дело десятое.
Re: паттерны экслюзивно для .net c#
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 30.03.14 09:30
Оценка: 136 (4)
Здравствуйте, -rsdn-, Вы писали:

R>нужны примеры с учетом платформы и языка программирования

R>в частности интересно что такое связность от связанность (cohesion & coupling)

О паттернах

Тут уже выше давали ссылку, что я начал публикацию постов именно по теме паттернов программирования в .NET, с примерами с учетом платформы .NET и языка программирования C#.

Хотя есть масса примеров GoF паттернов привязанной к платформе и языку программирования, я бы сказал, что паттерны больше привязаны к парадигме программирования (OOP vs. FP) нежели к языку, хотя культурные особенности платформы тоже присутствуют.

Вот несколько примеров:

Шаблонный Метод

Основная суть шаблонного метода в том, что базовый класс задает каркас алгоритма, а наследник переопределяет недостающие куски, но что если вместо наследования переменные шаги задавать с помощью анонимных методов? Поскольку C# в этом плане является мультипарадигменным языком (ОО + FP фичи), то этот подход вполне оправдан. Подход на основе делегатов является очень популярным решением, хотя и применяется зачастую локально в классе (я назвал его локальным методом шаблона). С другой стороны, локальный метод шаблона часто используется для выполнения некоторых действий не зависимо от исхода "основного шага алгоритма", что в других языках (таких как С++) реализуется с помощью идиомы RAII — Resource Aquisition is Initialization. Эта же идиома используется и в языке C# в виде блока using и Disposable паттерна (который является одним из многих платформенно-зависимых паттернов проектирования).

Но в C# есть и еще одна возможность, которая может быть использована для реализации паттерна Шаблонный Метод — методы расширения. В классическом шаблонном метод каркас алгоритма задается в виде (неполиморфного) метода базового класса, а шаги задаются за счет переопределения (обычно) защищенных методов. Но что если мы зададим алгоритм шаблонного метода вне базового класса — с помощью метода расширения, а переменные шаги делегируем открытым виртуальным методам интерфейса или абстрактного класса? (привет, LINQ) В некотором роде этот подход можно рассматривать как разновидность шаблонного метода, специфичного для конкретного языка программирования. Сходство будет более очевидным, если посмотреть на другие языки, такие как Java, в которой появилась аналогичная возможность, но несколько под другим соусом в виде Default Method Implementation.

Итератор

Поскольку перебор элементов коллекций является очень распространенной операцией, то паттерн итератор обычно очень сильно интегрируется в фреймворк или базовую библиотеку, при этом вид(-ы) итераторов сильно зависит от культурных особенностей языка/платформы.

Так, например, итератор в .NET представлен интерфейсами IEnumerable/IEnumerator и IEnumerable<T>/IEnumerator<T>, который является однонаправленным итератором только для чтения. При этом в других языках/платформах итераторы другие. Так, в С++ их огромное множество: есть однонаправленные, двунаправленные, random-access, реверсные итераторы и т.п.

С другой стороны, в языке C# есть синтаксический сахар для создания итераторов/генераторов — так называемый блок итераторов (подробнее смотри в Итераторы в C#. Часть 1, Часть 2, Часть 3). При этом блок итераторов начинает смещать акцент с итераторов к генераторам, граница которых начинает стираться.

Визитор

Есть такая общая проблема в computer science под названием expression problem, основная идея которой заключается в том, что разные парадигмы программирования предоставляют "точки расширения" в одной плоскости, усложняя расширение в другой. Так, в ООП очень легко добавить новый тип в иерархию типов и переопределить пару виртуальных методов (тот самый принцип Открыт-Закрыт), но при этом сложности возникают при попытке добавить новый абстрактный метод в базовый тип иерархии. С другой стороны, ФП и структурное программирование легко позволяет добавить новую операцию над семейством типов (в ФП языках за счет pattern-matching-а), усложняя добавление нового типа в это семейство.

В результате, в ООП, появились ряд паттернов проктирования, которые упрощают добавлять операции в иерархию типов в виде паттерна посетитель (визитор).

Тут тоже могут быть платформенно и языко-зависимые реализации, в виде попытки эмуляции pattern-matching-а в языке C#, что вполне будет работать для небольшой иерархии типов, с небольшой вероятностью добавления новых типов в эту иерархию и с большой вероятностью добавления новых операций.

О cohesion&coupling

Эти два понятия являются фундаментальными понятиями в проектировании ПО, хотя они применимы и за его пределами.
Давай рассмотрим распределенную команду разработчиков. Как сделать ее максимально эффективно? Для этого нужно сосредоточить в одной локацию людей, которые будут заниматься решением одной задачи с возможно минимальным количеством взаимодействия с другими локациями (это и есть low coupling), при этом решать эта команда должна работать не над разнородными задачами, а решать одну или родственные задачи (это и есть high cohesion).

Эта проблема есть и в дизайне. Класс/модуль/приложение должны минимально зависеть от других классов/модулей/приложений, что позволит думать, развивать и улучшать класс/модуль/приложение самостоятельно не ломая и не задумываясь о соседях (это low couping). При этом класс/модуль/приложение должен решать связанный набор задач, а не быть швейцарским ножом, который умеет гайки закручивать, отчеты отправлять и в базу данных ходить (это high cohesion; нарушение Single Responsibility Principla обычно подразумевает слабый cohesion).

При этом low couling подразумевает не только то, что класс должен знать о минимальном числе других классов (это самый простой вид каплинга — физический каплинг), но и зависеть от минимального числа других классов/модулей логически. Именно логическая связанность является самой злой, когда один класс предполагает, что в корне приложения есть код, который поместил реализацию этого интерфейса в контейнер; или предполагает, что некоторый код сохранил файл в определенном месте в определенном формате; или предполагает, что есть некий другой класс, который будет публиковать события через event aggregator. Нужно понимать, что слабая связанность подразумевает возможность анализа и развития класса А в отрыве от класса Б, не зависимо от того, знает ли класс А о существовании класса Б или лишь рассчитывает на его существование.

Coupling и паттерны программирования

Есть довольно простая, но весьма хорошая книга о паттернах проектирования, под названием Head-First Design Patterns, там есть хорошая фраза:
(основная суть паттернов проектирования): выделите переменные составляющие и инкапсулируйте их, чтобы позднее их можно было изменять или расширять без воздействия на постоянные составляющие..

В целом, эта мысль пронизывает и всю книгу банды четырех: как инкапсулировать процесс создания семейства объектов (абстрактная фабрика) так, чтобы клиенты не задумывались о конкретных типах? Как инкапсулировать процесс обхода составного объекта так, чтобы клиенты не знали о его внутренней структуре (итератор)? Как бесшовно добавлять новую функциональность, чтобы клиенты класса этого не замечали (декоратор) и т.п?

Т.е. суть большинства паттернов проектирования — это борьба со сложностью и устранение лишних связей, что позволит анализировать, понимать и изменять один аспект системы, не задумываясь о множестве других, не связанных с этой главной задачей.

З.Ы. У Ayende есть цикл постов по этой же теме — Design Patterns in the Test of Time
Re[7]: паттерны экслюзивно для .net c#
От: Sinclair Россия https://github.com/evilguest/
Дата: 31.03.14 06:12
Оценка:
Здравствуйте, Sinix, Вы писали:
S>Ну блин, это не паттерн в терминах оригинального GoF/Фаулера. Иначе мы так дойдём до "с++ — это сборник паттернов для ассемблера" и паттерн у нас превратится в баззворд, который обозначает так много, что не обозначает ничего.
Вы так говорите, как будто это плохо. Но С/С++ — это и есть набор паттернов для ассемблера. Точнее, С — для ассемблера, а С++ — для С.
Есть типовые проблемы, есть типовые решения. Иногда типовое решение типовой проблемы встраивают сразу в язык.
Например, в Java property — это паттерн, а в Delphi — конструкция языка. Publisher/Subscriber в Delphi — это паттерн (встроенные события там слишком убоги), а в C# — это конструкция языка. И так далее.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[8]: паттерны экслюзивно для .net c#
От: Sinix  
Дата: 31.03.14 06:57
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>>Ну блин, это не паттерн в терминах оригинального GoF/Фаулера. Иначе мы так дойдём до "с++ — это сборник паттернов для ассемблера" и паттерн у нас превратится в баззворд, который обозначает так много, что не обозначает ничего.

S>Вы так говорите, как будто это плохо. Но С/С++ — это и есть набор паттернов для ассемблера. Точнее, С — для ассемблера, а С++ — для С.

По большому счёту да, но тогда мы уходим в область философии, где все правы, но по-разному
Обычно всё-таки под паттернами понимают термины из gof/фаулера.

S>Есть типовые проблемы, есть типовые решения. Иногда типовое решение типовой проблемы встраивают сразу в язык.

S>Например, в Java property — это паттерн, а в Delphi — конструкция языка. Publisher/Subscriber в Delphi — это паттерн (встроенные события там слишком убоги), а в C# — это конструкция языка. И так далее.

Угу. Но:
1. Если всё это обзывать паттернами, то как отличать благие пожелания по, например, обсерверу в GoF от железобетонной реализации event-ов в c#?
2. Мы начинаем путать паттерны как описание проблемы (выше кучу раз упоминался пост
Автор: XopoSHiy
Дата: 14.04.10
от XopoSHiy) и паттерны как инструмент для решения проблем. Они не обязательно относятся как один-к-одному, достаточно вспомнить холивары на тему "вот код — это посредник, фасад, мост или адаптер?" без приведения проблемы, которую этот код пытается решить.
3. В результате путаницы появляются кошмарики типа вот этого (pdf, ссылка от -n1l-). Посмотрите примеры, там буквально каждый из разряда "обнять и плакать"
Re[9]: События
От: Qbit86 Кипр
Дата: 31.03.14 07:34
Оценка:
Здравствуйте, Sinix, Вы писали:

S>>Publisher/Subscriber в Delphi — это паттерн (встроенные события там слишком убоги), а в C# — это конструкция языка.


Вы так говорите, будто в C# события не убоги.

S>1. Если всё это обзывать паттернами, то как отличать благие пожелания по, например, обсерверу в GoF от железобетонной реализации event-ов в c#?


Что такое «железобетонная реализация event'ов» в C#? Вместо неё гораздо приятнее использовать Обсервер из Rx, который как раз примерно по GoF.
Глаза у меня добрые, но рубашка — смирительная!
Re[10]: События
От: Sinix  
Дата: 31.03.14 08:23
Оценка:
Здравствуйте, Qbit86, Вы писали:

Q>Вы так говорите, будто в C# события не убоги.

Если их использовать по назначению — нет, не убоги.

Q>Что такое «железобетонная реализация event'ов» в C#?

Для обсервера gof я с ходу могу предложить варианта 4 реализации, причём общего у них будет только то, что они позволяют получать оповещения.
Когда мы говорим про события шарпа, то уточнений про что мы собственно говорим обычно делать не надо

Q>Вместо неё гораздо приятнее использовать Обсервер из Rx, который как раз примерно по GoF.

У обычных событий и у IObservable сценарии использования практически не пересекаются, поэтому утверждать что A однозначно лучше B не выйдет.
Re[11]: События
От: Qbit86 Кипр
Дата: 31.03.14 08:30
Оценка:
Здравствуйте, Sinix, Вы писали:

Q>>Вы так говорите, будто в C# события не убоги.

S>Если их использовать по назначению — нет, не убоги.

Ну и какое у них назначение?

S>У обычных событий и у IObservable сценарии использования практически не пересекаются, поэтому утверждать что A однозначно лучше B не выйдет.


Сценарии использования обычных событий строго включены в сценарии использования IObservable. Если б не легаси в повсеместном использовании встроенных событий стандартными и сторонними библиотеками, пользоваться встроенными событиями смысла вообще нет.
Глаза у меня добрые, но рубашка — смирительная!
Re[12]: События
От: Sinix  
Дата: 31.03.14 09:08
Оценка:
Здравствуйте, Qbit86, Вы писали:

S>>Если их использовать по назначению — нет, не убоги.

Q>Ну и какое у них назначение?

Для событий — привязка дополнительного кода для компонент (в основном ui-компонент) для обработки единичных событий.
Для observable — управление последовательностью однотипных событий.


S>>У обычных событий и у IObservable сценарии использования практически не пересекаются, поэтому утверждать что A однозначно лучше B не выйдет.

Q>Сценарии использования обычных событий строго включены в сценарии использования IObservable.

Скажем так: я имел опыт использования в продакшне и событий для того, что решалось Rx, и Rx для того, что решалось событиями. С тех пор я очень скептически отношусь к фанатизму аля "события устарели т.к. появился Rx".

Проблем (явных и неявных) всплывает куча. В основном:
1. Пользователи API начинают накручивать сложные сценарии со своими шедулерами там, где поставщик API их не ждёт. В результате на ровном месте возникают очень неприятные race conditions, которые очень любят всплывать непосредственно у клиентов.
2. Последовательности начинают использовать как события — с "тяжёлым" кодом в подписчиках, бросанием исключения в надежде на "перехватится выше по стеку", запуском асинхронных задач и "отменой" последовательностей. Работает, но поддерживаемость кода падает в разы.
3. Необходимость протаскивать disposable для отписки. Каждый решал проблему по своему, получалось не всегда.

Если бы это были единичные случаи, или повторялось только у отдельных разработчиков, или подобные косяки отлавливались бы статическим анализом, то с большей частью проблем можно было бы смириться (нравится людям — пусть пишут). По факту дешевле выходит не создавать себе проблем на ровном месте и использовать специализированный инструмент — события.


Чтобы совсем не было оффтопом. С большинством "универсальных" паттернов выходит ровно та же фигня: вместо готового инструмента изобретаем универсальный, а затем допиливаем подпорками до того, что можно решить на голом шарпе. Всей разницы: получили ещё один велосипед для изучения
Re[13]: События
От: Qbit86 Кипр
Дата: 31.03.14 10:44
Оценка:
Здравствуйте, Sinix, Вы писали:

S>1. Пользователи API начинают накручивать сложные сценарии со своими шедулерами там, где поставщик API их не ждёт. В результате на ровном месте возникают очень неприятные race conditions, которые очень любят всплывать непосредственно у клиентов.


Так это и с обычными событиями можно наворотить. Звучит так: «Давайте запретим вилки, так как дети могут их засунуть в розетки; взамен будем пользоваться вязальными спицами.»

S>2. Последовательности начинают использовать как события — с "тяжёлым" кодом в подписчиках


Не вижу, каким образом «.Subscribe(...)» заставляет пользователей использовать более тяжелый код, а «+= ...» — нет. В первом случае хотя бы лямбды можно использовать.

S>бросанием исключения в надежде на "перехватится выше по стеку"


То ли дело стандартные события, где исключение в одном из обработчиков внезапно влияет на остальных подписчиков.

S>3. Необходимость протаскивать disposable для отписки.


Это совсем смешно. Ты всерьёз утверждаешь, что протаскивать и источник, и подписчик событий проще, чем один только безликий IDisposable?

S>По факту дешевле выходит не создавать себе проблем на ровном месте и использовать специализированный инструмент — события.


Увы, иногда дешевле. В этом вся суть консервации принятых некогда кривых решений.
Глаза у меня добрые, но рубашка — смирительная!
Re[14]: События
От: Sinix  
Дата: 31.03.14 11:24
Оценка:
Здравствуйте, Qbit86, Вы писали:

S>>1. Пользователи API начинают накручивать сложные сценарии со своими шедулерами там, где поставщик API их не ждёт. В результате на ровном месте возникают очень неприятные race conditions, которые очень любят всплывать непосредственно у клиентов.

Q>Так это и с обычными событиями можно наворотить. Звучит так: «Давайте запретим вилки, так как дети могут их засунуть в розетки; взамен будем пользоваться вязальными спицами.»
Нет. Для событий достаточно
someObj.SomeEvent += SomeHandler;


Для Rx подобного сахара нет и не предвидится по той же причине, по которой нет сахара для infoof. В результате клиенты обычно подрубают к себе в проект System.Reactive и начинают ваять свои последовательности т.к. "это ж легко". Если API выставляет события там, где они по логике больше подходят, такой фигни не возникает.

Ну, и не забываем про веселуху с обновлением rx в продукте, чтобы не поиметь приключений с несколькими версиями одной библиотеки в процессе. Сейчас не так актуально, в момент появления Rx было проблемой.

S>>2. Последовательности начинают использовать как события — с "тяжёлым" кодом в подписчиках

Q>Не вижу, каким образом «.Subscribe(...)» заставляет пользователей использовать более тяжелый код, а «+= ...» — нет.
Пойнт не в этом. Обычные события такую штуку легко переживают, т.к. редко используются для обслуживания "горячего" потока данных. Observable — далеко не всегда. Пользователи начинают путаться и дуть на воду, т.е. запускать свой код через отдельный шедулер и тем самым порождают ещё больше race conditions.

Q>То ли дело стандартные события, где исключение в одном из обработчиков внезапно влияет на остальных подписчиков.

Напоминаю, речь про типовой для событий сценарий aka компонент-подписчик. "Остальных подписчиков" в 99.999% случаев просто не бывает.

S>>3. Необходимость протаскивать disposable для отписки.

Q>Это совсем смешно. Ты всерьёз утверждаешь, что протаскивать и источник, и подписчик событий проще, чем один только безликий IDisposable?
Его вообще не надо протаскивать, источник как правило доступен всё время жизни подписчика.
Re[9]: паттерны экслюзивно для .net c#
От: Sinclair Россия https://github.com/evilguest/
Дата: 31.03.14 13:35
Оценка:
Здравствуйте, Sinix, Вы писали:

S>По большому счёту да, но тогда мы уходим в область философии, где все правы, но по-разному

Нет, мы уходим в область научного подхода к решению проблем.
S>Обычно всё-таки под паттернами понимают термины из gof/фаулера.
Это очень странный подход. Всё равно, как под термином "задача" понимать ровно задания из Демидовича, а всё остальное считать философией.

S>Угу. Но:

S>1. Если всё это обзывать паттернами, то как отличать благие пожелания по, например, обсерверу в GoF от железобетонной реализации event-ов в c#?
Очень просто: также, как вы отличаете int i=0; в вашей программе от понятия "переменная".
Ещё раз подчеркну: event в C# — это уже не паттерн, это конструкция языка. Эта конструкция реализует некоторое архитектурное решение, которое в языках без нативной поддержки event-ов называется publisher/subscriber.

S>2. Мы начинаем путать паттерны как описание проблемы (выше кучу раз упоминался пост
Автор: XopoSHiy
Дата: 14.04.10
от XopoSHiy) и паттерны как инструмент для решения проблем.

При всём уважении к XopoSHiy не стоит относиться к его посту как к священному писанию. Кроме того, вы ударяетесь в другую крайность.
XopoSHiy поясняет, что один и тот же код может быть реализацией различных паттернов, в зависимости от решаемой задачи. Но ведь и достаточно различный код может быть решением одной и той же задачи. Поэтому сводить паттерн исключительно к задаче — странно. Паттерн — это удачный приём, сочетание задачи и решения.
При этом интуитивно ожидается, что решение будет нетривиальным, поэтому конструкции языка паттернами не называют.

S>3. В результате путаницы появляются кошмарики типа вот этого (pdf, ссылка от -n1l-). Посмотрите примеры, там буквально каждый из разряда "обнять и плакать"

Ну, это уже чистый постмодернизм — искусство ради искусства.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[10]: паттерны экслюзивно для .net c#
От: Sinix  
Дата: 01.04.14 04:52
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>>>Но С/С++ — это и есть набор паттернов для ассемблера

S>>По большому счёту да, но тогда мы уходим в область философии, где все правы, но по-разному
S>Нет, мы уходим в область научного подхода к решению проблем.

Странный спор какой-то получается.
С одной стороны, очевидно, что называть абстракции GoF, конкретные рекомендации из FDG и ещё более конкретные конструкции языка одним термином — прямой путь к замыливанию контекста.
С другой — мне уже три человека продолжают доказывать, что всё едино, хотя на практике, я уверен, сами такой терминологией никогда не пользуются

В общем я самоустраняюсь, т.к. смысла в продолжении никакого не вижу. Участникам спасибо, приятно было поспорить!
Re[11]: паттерны экслюзивно для .net c#
От: Sinclair Россия https://github.com/evilguest/
Дата: 01.04.14 06:10
Оценка:
Здравствуйте, Sinix, Вы писали:

S>С другой — мне уже три человека продолжают доказывать, что всё едино, хотя на практике, я уверен, сами такой терминологией никогда не пользуются

По-моему, вы как-то превратно понимаете аргументацию. Вы можете ткнуть в то место, где я предлагаю вам называть конструкции языка паттернами?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.