Читать «Рефакторинг с использованием шаблонов» онлайн - страница 13

Джошуа Кериевски

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

Панацея шаблонов проектирования

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

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

Однажды моя чрезмерная увлеченность стала совершенно очевидной. Я программировал в паре — мы с партнером должны были написать класс, использующий Java-интерфейс TreeModel, чтобы отобразить на экране диаграмму объектов Spec в виде дерева. Наш код работал, но дерево отображало каждый объект Spec, используя вызов его метода toString (), который не возвращал необходимую нам информацию об объекте Spec. Мы не могли изменить метод toString () объекта Spec, поскольку от него зависели другие части системы. Итак, мы сосредоточились на том, как решить нашу задачу. Действуя по привычке, я обдумал, какие шаблоны могут помочь. На ум пришел шаблон Decorator, и я предложил использовать его для того, чтобы обернуть Spec в объект, который может перегрузить метод toString (). Ответ моего партнера на это предложение удивил меня: “Использование для этой цели Decorator похоже на применение кувалды к проблеме, для которой достаточно нескольких легких втулок с маленьким молотком”. Его решение состояло в том, чтобы создать небольшой класс с названием NodeDisplay, конструктор которого получает в качестве аргумента экземпляр Spec, а единственный открытый метод toString () получает от экземпляра Spec необходимую информацию. Класс NodeDisplay практически не требовал времени для программирования, поскольку состоял менее чем из 10 простых строчек кода. Мое решение с Decorator привело бы к написанию по меньшей мере 50 строк кода со множеством повторяющихся передач вызовов к экземпляру Spec.