воскресенье, 8 февраля 2009 г.

Почему я недолюбливаю паттерны проектирования?

Я обещал Дмитрию Вьюкову рассказать, почему же я недолюбливаю паттерны проектирования. Выполняю обещание. Бум вокруг паттернов уже схлынул (что есть хорошо), но в его время вокруг паттернов уже было сломано множество копий. Так что, наверное, я не скажу здесь ничего нового.

Итак, почему же я недолюбливаю паттерны проектирования?

Первая причина историческая. По молодости мне приходились заниматься графикой (поддержка мнемосхем технологических процессов, включая редактор этих мнемосхем). А в графике термин паттерн, насколько я помню, относился к стилю линии (пунктир, точки, точки с пунктиром) и стилям заливки. В Borland-овской библиотеке BGI даже были функции со словом pattern в названии: setfillpattern, например. Так что, когда в районе 2000-го начался шум вокруг паттернов, у меня был жуткий психологический дискомфорт -- термин, к которому я уже привык, вдруг стал использоваться совсем в другой интерпретации.

Вторая причина в том, что я время от времени забывал, что именно скрывается за названием некоторых паттернов. Ну не очень хорошая у меня память и если я долго не пользуюсь каким-то термином, то мне бывает трудно вспомнить, что же именно за этим термином спрятано. А одно из назначений паттернов как раз в том, чтобы создать общий словарь для проектировщиков. Мол, скажет один член проектной команды: "Я собираюсь использовать здесь паттерн Bridge", а все остальные должны сразу же понять, что он имел в виду. Но вот я с ходу не могу сказать, чем Bridge отличается от Proxy. Или же вспомнить, в чем суть паттернов State или Strategy.

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

И это как раз четвертая причина: почему паттернам уделяется такое большое внимание? Когда я читал эту знаменитую книгу о паттернах, очень часто я ловил себя на мыслях о том, что ряд описанных в книге паттернов уже давным-давно мной используются. Скажем, такие паттерны, как Command и Proxy вообще, как мне кажется, сами собой выводятся из идей объектно-ориентированного программирования. Поэтому мне было удивительно, почему таким простым и тривиальным вещам уделяется столько времени. Отмечу, что речь идет только о некоторых паттернах описанных в книге банды четырех. Часть паттернов были для меня открытием (вроде State, Strategy, Flyweight и Visitor), но я склонен объяснить это тем, что мне просто не приходилось решать задач, в которых эти паттерны были бы очень нужны (а по поводу полезности паттернов State и Strategy у меня до сих пор есть большие сомнения).

Пятая причина в том, что я очень сомневаюсь, что паттерны проектирования выводятся из каких-то действительно частых случаев использования одних и тех же приемов проектирования. Просто потому, что паттернов как-то многовато. Складывается впечатление, что на волне интереса к паттернам за последние стали выдавать практически все, что удавалось придумать и реализовать тем или иным авторам. Даже если их идеи находили свое воплощение всего один раз.

Шестая причина перекликается с пятой. Описанные в книге банды четырех паттерны предназначены для использования в объектно-ориентированных языках со статической типизаций вроде C++, Java, C# или Eiffel. Для динамически-типизированных языков не все паттерны актуальны, к примеру, Visitor не имеет смысла для языков вроде Smalltalk, Ruby или Python. Не говоря уже о функциональных языках. Т.е. получается, что паттерны являются не столько паттернами проектирования, сколько паттернами реализации более высокоуровневых проектных решений. Но все же и не паттернами реализации, поскольку реализация паттернов в коде -- это отдельная задача (см. ниже восьмую причину). Так что не очень понятно, на какой уровень проектирования паттерны рассчитаны.

Седьмая причина в том, что я пару раз наблюдал, как следование паттернам превращается в что-то вроде ортодоксальной религии. Мол, есть паттерн Visitor и нужно его использовать так, как он есть. И ни шагу влево, ни шагу вправо. Понятно, что сами паттерны не виноваты. Виноват, скорее тот шум, который вокруг них был создан. Но осадочек-то остался :)

Ну и восьмая причина в том, что паттерны -- это не готовый код, не библиотека, которую можно подключить к своему проекту и использовать. Это идеи (некоторые из которых довольно тривиальные и лежащие на поверхности). Причем идеи из очень специфической категории - идеи, ценность которых без реализации не очень высока. А это значит, что разрабочик, может быть, и получает какой-то выигрыш, когда оперирует паттернами. Но он все равно оказывается перед серьезной пропастью -- несоответствием между своим высокоуровневым проектным решением и кодом, который ему предстоит написать. И я сомневаюсь, что паттерны помогают ему эту пропасть преодолевать (скорее они даже увеличивают ее). По крайней мере для таких языков, как С++, Java, C#, Eiffel, D. В частности, попробуйте реализовать потокобезопасный паттерн Singleton для C++. Поэтому для меня предложение вида "Попробуйте использовать здесь паттерн Bridge" аналогично предложению "А вот здесь расскажите анекдот про тещу". Какой анекдот, для какой аудитории? Должен ли он быть с тайным смыслом или плоским, пошлым или детским, из разряда "черных" или добрым, абсолютно новым или знакомым всем присутствующим? Паттерны об этом не говорят. И это, на мой взгляд, не есть хорошо.

Вот такие пироги. Все вышесказанное является злостным ИМХО и не претендует на звание абсолютной истины :)

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