Обзор книги «Паттерны проектирования на платформе .NET»
Как известно, недавно была опубликована книга по паттернам проектирования за авторством Сергея Теплякова.Дабы поддержать мною уважаемого нашего разработчика (сам Сергей, несмотря на переезд заграницу, всё ещё считает себя нашим — за пруфом идите к нему в блог), не пожалел денег и сразу же купил электронную версию. До этого я читал банду четырёх и Design Patterns Head First, поэтому, в принципе, есть с чем сравнить.Книга занимает чуть более 300 страниц, что вполне можно осилить за неделю неторопливого чтения. Книга разбита на 4 части:
- Паттерны поведения
- Порождающие паттерны
- Структурные паттерны
- Принципы проектирования
Разбиение паттернов на такие группы уже давно устоялось и прижилось. В отличие от банды четырёх в книге Сергея есть глава, посвящённая SOLID-принципам проектирования (собственно, в книге банды четырёх этих принципов в том виде, в котором мы с ними знакомы и быть не могло, поскольку были сформулированы позже). В книге банды четырёх есть практическая глава, которая иллюстрирует паттерны на примере разработки текстового редактора. На протяжении всего текста в качестве примеров Сергеем используются проблемы, возникающие при разработке приложения по обработке логов (как я понял, тема близкая к тому, чем сейчас занимается Сергей в компании Майкрософт). Отдельной практической главы, как в случае с бандой четырёх нет. В принципе, автору неплохо удаётся разбирать паттерны на таком примере, однако, хотелось бы заметить, что всё даётся слишком легко, то есть, по ходу повествования особых проблем не возникает — всё ложится как по маслу. Скорее всего, так и было задумано при написании, но мне показалось не очень приятным, что нигде нет челленджа (извините, за варваризм). Пример с текстовым редактором выглядит поинтереснее, на мой взгляд. К недостаткам книги я это замечание отнести напрямую, конечно же, не могу.
Эта книга — тот редкий случай, когда я просто взял книгу и прочитал её от начала и до конца. И должен вам сказать, что книга читается очень и даже очень легко. Конечно, разработчик, только начавший своё ознакомление с паттернами, вряд ли сможет так беззаботно прочитать всю книгу, но, думаю, что для новичка всё равно трудно представить книгу более простую для понимания, чем эта. Более глубокому пониманию паттернов способствует стиль и форма изложения, выбранная автором: книга во многом является отражением собственного опыта, а не тупой компиляцией чужих мыслей, и это очень импонирует. Примеры, несмотря на то, что выбранный тип приложения мне не очень понравился, всё равно хороши и со своей задачей справляются. Для не новичков может оказаться интересным сравнить свой опыт с авторским. Зачастую я находил подтверждения свои собственным мыслям, которые мне не с кем было обсудить. Поэтому, лично у меня, в процессе чтения книги постоянно происходил внутренний диалог с автором.
Что касается целевой аудитории книги, то хотелось бы заметить, что хоть в .NET и есть множество собственных плюшек, но таких плюшек, которые оказывали бы огромное влияние на форму паттернов совсем мало. С разбегу могу вспомнить только то, что в .NET можно сделать явную реализацию интерфейса и упростить некоторые паттерны, используя делегаты. Ну и да — нет множественного наследования, что, например, Боб Мартин считает, по сути, косяком команды .NET, поскольку «deadly diamond of death» не настолько страшен, как его малюют, зато множественное наследование в некоторых случаях может оказаться очень полезным (хотя, случается это не сказать, чтобы часто). Поскольку особенностей платформы .NET не так много, то книгу могут читать все кто интересуются паттернами, в независимости от языкаисповедания.
Автор приводит классические диаграммы паттернов, которые густо используют наследование, но очень часто даёт упрощённые варианты, поскольку в классическом виде паттерны используются достаточно редко. В целом, автор не забывает указать, что не следует вслепую использовать паттерны и учит включать мозг, танцуя от задачи и требований. Отмечу также, немаловажным является то, что использование паттернов рассматривается в связке с написанием unit-тестов.
В теме, где Сергей анонсировал то, что он пишет книгу, нашлись люди, которые не преминули сказать, что «паттерны — фигня, вот обчитаются люди, а потом делают фабрики фабрик фабрик фабрик с мегафасадами и ещё 100500 паттернов там, где не надо, зачем все эти книги по паттернам, все эти паттерны и так понятны». По моему скромному мнению, большая часть таких людей пишет нечитабельный underengineered говнокод, который потом переписывают по тысяче раз. Это раз. Во-вторых, да, бездумное применение паттернов — плохо и в хорошей книге об этом тоже написано. Программирование это инженерия, а в инженерии нет серебряных пуль и универсальных ответов на все вопросы. Поэтому хорошие программисты всегда взвешивают, что они ставят на кон и что готовы принести на алтарь сложности в целях решения задачи. К сожалению, не бывает книг, которые учат такому искусству (если кто такие видел — поделитесь), ибо достичь понимания того, как соблюсти баланс между сложностью, простотой и мощностью решений можно только с помощью многих лет упорных тренировок на реальных задачах.Мне понравилась в книге мысль о том, что следование (даже правильное и хорошее следование) всем принципам не даёт гарантии достижения шикарного дизайна приложения. Всё зависит от задачи, от того как ООП ляжет на такую задачу, в конце-то концов.
В книге не рассмотрены следующие классические паттерны: «bridge», «flyweight», «chain of responsibility», «memento», «prototype».Паттерн «prototype» довольно тупой и реализуется через ужасный ICloneable (не даёт понимания того, что это за копия — глубокая или поверхностная), хотя, реализацию, конечно, можно улучшить. Может быть, поэтому этот паттерн был исключён из книги. Остальные паттерны достаточно интересны и я не знаю, почему они были исключены из рассмотрения. В книге также не рассматриваются всякие «составные» паттерны, типа MVC, MVP, MVVM. Вернее, они затрагиваются мимолётом, но автор в них не углубляется, и, думается, это правильно, поскольку каждому из них можно посвятить отдельную книгу.
Одним из немногих моментов, где я не совсем согласен с автором явился момент насчёт выброса недекларированных исключений наследниками, если эти исключения не прописаны в контракте базового класса, или не указаны в XML-комментариях в соответствующем разделе. Указывать возможные исключения, декларировать их в контрактах (я не пользовался контрактами, но по книге понял, что задекларировать возможные типы исключений можно) — не является плохой практикой, но это особо ничего не даёт, кроме ложной уверенности в том, что из вызываемого кода будут лететь только задекларированные исключения. Сколько вы методов видели в BCL, которые лезут, скажем, в файловую систему и декларируют все типы возможных исключений? Правильно, таких методов нет. От концепции проверяемых исключений разработчики .NET отказались изначально. Система обработки ошибок через исключения по-прежнему является большим и жирным геморроем для тех, кто хочет разрабатывать стабильные приложения. Для правильной обработки ошибок через исключения требуется многое: грамотное построение архитектуры, грамотное выделение типов исключений, грамотное написание тестов, контрактов и прочее. Если хотя бы в одной из этих сфер у команды разработчиков есть проблемы, то приложение будет падать с завидной регулярностью, причём зачастую от всяких «безобидных исключений», когда работу можно было бы и продолжить.
В заключение хотелось бы сказать спасибо Сергею за замечательную книгу, пишите ещё! По десятибалльной шкале я бы оценил книгу в 8–8.5.