вторник, 13 июля 2010 г.

C# 3.0 Design Patterns

Вступление
Почувствовал недавно, что подзабыл паттерны объектно-ориентированного проектирования - решил освежить память.

Перечитывать классическую книгу по этой тематике - "Design Patterns: Elements of Reusable Object-Oriented Software" (aka Gang of Four = GoF) - настроя не было: хотелось найти книгу посвежее (а за 15 лет по мотивам GoF было издано немало книг). Прошерстив Amazon, я остановился на книге "C# 3.0 Design Patterns". Как .NET-разработчика меня не в последнюю очередь привлекло название: интересно было посмотреть, какие изюминки автор видит в портировании паттернов на C# 3.0. Противоречивые отзывы на Амазоне настораживали, но любопытство взяло свое.

После прочтения книги остались двоякие впечатления. С одной стороны, были интересные примеры и идеи, с другой, - остался осадок: встречались неполные описания паттернов, не очень подходящие примеры и т. д. Но могу смело сказать, что с поставленной задачей книга справилась (пусть и отчасти косвенным образом): паттерны я вспомнил. Причем это тот случай, когда "не было бы счастья, да несчастье помогло": моменты, освещенные в книге не самым лучшим образом, заставили меня обратиться к GoF, сравнить материал двух книг, и в результате лучше разобраться в этой теме.

Негатив

Factory method и Abstract factory

В главе про FactoryMethod описывается и реализуется Parameterized Factory Method. Традиционный дизайн этого паттерна (когда тип создаваемого объекта переопределяется в виртуальном методе наследника) остается за кадром. Видимо, поэтому в главе про Abstract Factory автор не упоминает, что приведенный дизайн Abstract Factory - вариация на тему Abstract Method. Кроме того, при описании Abstract Factory опускается альтернативный дизайн этого паттерна, построенный на паттерне Prototype (этот дизайн интересен своей гибкостью).

Bridge

Сравним выдержки из описания паттерна Bridge из GoF:
An adapter often becomes necessary when you discover that two incompatible classes should work together, generally to avoid replicating code. The coupling is unforeseen. In contrast, the user of a bridge understands up-front that an abstraction must have several implementations, and both may evolve independently. The Adapter pattern makes things work after they're designed; Bridge makes them work before they are.

и "C# 3.0 Design Patterns":
The Bridge pattern decouples an abstraction from its implementation, enabling them to vary independently. The Bridge pattern is useful when a new version of software is brought out that will replace an existing version, but the older version must still run for its existing client base.

GoF рекомендует закладывать использование Bridge заранее, а "C# 3.0 Design Patterns" заявляет, что паттерн отлично подходит для legacy-кода. Из оперы "точно так же, но наоборот". Мое понимание паттерна Bridge совпадает с трактовкой GoF, и пример из главы про Bridge, остался для меня загадкой.

Mediator

В GoF паттерн Mediator описывается на знакомом каждому разработчику примере взаимодействия визуальных объектов на форме. При этом показывается, как Mediator позволяет уменьшить связность и сосредоточить логику, которая иначе была бы "размазана" по множеству объектов или обработчиков событий, в одном месте. В "C# 3.0 Design Patterns", в свою очередь, приводится невыразительный пример взаимодействия объектов через Mediator, причем акцент сделан на общении объектов, а не на логике внутри Mediator.

Все так плохо?

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

Однако "C# 3.0 Design Patterns" имеет смысл прочитать/пролистать .NET разработчикам, которые уже изучили фундаментальный труд по этой тематике.

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

Во-вторых, реализация некоторых паттернов имеет занимательную специфику по отношению либо к C#, либо к .NET в целом. Например, мне показалась интересной реализация паттерна Visitor на базе рефлексии. Конечно, то еще извращение, но при работе с legacy-кодом может пригодиться.

Вместо заключения

В блоге у Jason McDonald есть отличная шпаргалка по GoF паттернам. Незаменимая штука, если вам нужно быстро вспомнить, кто есть кто.

Комментариев нет: