Как известно, недавно была опубликована книга по паттернам проектирования за авторством Сергея Теплякова.

Дабы поддержать мною уважаемого нашего разработчика (сам Сергей, несмотря на переезд заграницу, всё ещё считает себя нашим — за пруфом идите к нему в блог), не пожалел денег и сразу же купил электронную версию. До этого я читал банду четырёх и Design Patterns Head First, поэтому, в принципе, есть с чем сравнить.
Книга занимает чуть более 300 страниц, что вполне можно осилить за неделю неторопливого чтения. Книга разбита на 4 части:

  1. Паттерны поведения
  2. Порождающие паттерны
  3. Структурные паттерны
  4. Принципы проектирования

Разбиение паттернов на такие группы уже давно устоялось и прижилось. В отличие от банды четырёх в книге Сергея есть глава, посвящённая SOLID-принципам проектирования (собственно, в книге банды четырёх этих принципов в том виде, в котором мы с ними знакомы и быть не могло, поскольку были сформулированы позже). В книге банды четырёх есть практическая глава, которая иллюстрирует паттерны на примере разработки текстового редактора. На протяжении всего текста в качестве примеров Сергеем используются проблемы, возникающие при разработке приложения по обработке логов (как я понял, тема близкая к тому, чем сейчас занимается Сергей в компании Майкрософт). Отдельной практической главы, как в случае с бандой четырёх нет. В принципе, автору неплохо удаётся разбирать паттерны на таком примере, однако, хотелось бы заметить, что всё даётся слишком легко, то есть, по ходу повествования особых проблем не возникает — всё ложится как по маслу. Скорее всего, так и было задумано при написании, но мне показалось не очень приятным, что нигде нет челленджа (извините, за варваризм). Пример с текстовым редактором выглядит поинтереснее, на мой взгляд. К недостаткам книги я это замечание отнести напрямую, конечно же, не могу.

Эта книга — тот редкий случай, когда я просто взял книгу и прочитал её от начала и до конца. И должен вам сказать, что книга читается очень и даже очень легко. Конечно, разработчик, только начавший своё ознакомление с паттернами, вряд ли сможет так беззаботно прочитать всю книгу, но, думаю, что для новичка всё равно трудно представить книгу более простую для понимания, чем эта. Более глубокому пониманию паттернов способствует стиль и форма изложения, выбранная автором: книга во многом является отражением собственного опыта, а не тупой компиляцией чужих мыслей, и это очень импонирует. Примеры, несмотря на то, что выбранный тип приложения мне не очень понравился, всё равно хороши и со своей задачей справляются. Для не новичков может оказаться интересным сравнить свой опыт с авторским. Зачастую я находил подтверждения своим собственным мыслям, которые мне не с кем было обсудить. Поэтому, лично у меня, в процессе чтения книги постоянно происходил внутренний диалог с автором.

Что касается целевой аудитории книги, то хотелось бы заметить, что хоть в .NET и есть множество собственных плюшек, но таких плюшек, которые оказывали бы огромное влияние на форму паттернов совсем мало. С разбегу могу вспомнить только то, что в .NET можно сделать явную реализацию интерфейса и упростить некоторые паттерны, используя делегаты. Ну и да — нет множественного наследования, что, например, Боб Мартин считает, по сути, косяком команды .NET, поскольку «deadly diamond of death» не настолько страшен, как его малюют, зато множественное наследование в некоторых случаях может оказаться очень полезным (хотя, случается это не сказать, чтобы часто). Поскольку особенностей платформы .NET не так много, то книгу могут читать все кто интересуются паттернами, в независимости от языкаисповедания.

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

В теме, где Сергей анонсировал то, что он пишет книгу, нашлись люди, которые не преминули сказать, что «паттерны — фигня, вот обчитаются люди, а потом делают фабрики фабрик фабрик фабрик с мегафасадами и ещё 100500 паттернов там, где не надо, зачем все эти книги по паттернам, все эти паттерны и так понятны». По моему скромному мнению, большая часть таких людей пишет нечитабельный underengineered говнокод, который потом переписывают по тысяче раз. Это раз. Во-вторых, да, бездумное применение паттернов — плохо и в хорошей книге об этом тоже написано. Программирование это инженерия, а в инженерии нет серебряных пуль и универсальных ответов на все вопросы. Поэтому хорошие программисты всегда взвешивают, что они ставят на кон и что готовы принести на алтарь сложности в целях решения задачи. К сожалению, не бывает книг, которые учат такому искусству (если кто такие видел — поделитесь), ибо достичь понимания того, как соблюсти баланс между сложностью, простотой и мощностью решений можно только с помощью многих лет упорных тренировок на реальных задачах.

Мне понравилась в книге мысль о том, что следование (даже правильное и хорошее следование) всем принципам не даёт гарантии достижения шикарного дизайна приложения. Всё зависит от задачи, от того как ООП ляжет на такую задачу, в конце-то концов.

В книге не рассмотрены следующие классические паттерны: «bridge», «flyweight», «memento», «prototype».
Паттерн «prototype» довольно тупой и реализуется через ужасный ICloneable (не даёт понимания того, что это за копия — глубокая или поверхностная), хотя, реализацию, конечно, можно улучшить. Может быть, поэтому этот паттерн был исключён из книги. Остальные паттерны достаточно интересны и я не знаю, почему они были исключены из рассмотрения. В книге также не рассматриваются всякие «составные» паттерны, типа MVC, MVP, MVVM. Вернее, они затрагиваются мимолётом, но автор в них не углубляется, и, думается, это правильно, поскольку каждому из них можно посвятить отдельную книгу.

Одним из немногих моментов, где я не совсем согласен с автором явился момент насчёт выброса недекларированных исключений наследниками, если эти исключения не прописаны в контракте базового класса, или не указаны в XML-комментариях в соответствующем разделе. Указывать возможные исключения, декларировать их в контрактах (я не пользовался контрактами, но по книге понял, что задекларировать возможные типы исключений можно) — не является плохой практикой, но это особо ничего не даёт, кроме ложной уверенности в том, что из вызываемого кода будут лететь только задекларированные исключения. Сколько вы методов видели в BCL, которые лезут, скажем, в файловую систему и декларируют все типы возможных исключений? Правильно, таких методов нет. От концепции проверяемых исключений разработчики .NET отказались изначально. Система обработки ошибок через исключения по-прежнему является большим и жирным геморроем для тех, кто хочет разрабатывать стабильные приложения. Для правильной обработки ошибок через исключения требуется многое: грамотное построение архитектуры, грамотное выделение типов исключений, грамотное написание тестов, контрактов и прочее. Если хотя бы в одной из этих сфер у команды разработчиков есть проблемы, то приложение будет падать с завидной регулярностью, причём зачастую от всяких «безобидных исключений», когда работу можно было бы и продолжить.

В заключение хотелось бы сказать спасибо Сергею за замечательную книгу, пишите ещё! По десятибалльной шкале я бы оценил книгу в 8-8.5.