Бизнес-логика на страже качества |
29.09.2008 10:25 |
Публикация компании SEADMEX Качество программного обеспечения всегда было одним из «больных вопросов» для пользователей и для разработчиков. Кого ни спроси, все обязательно борются за качество. Что характерно, многие действительно борются, применяя тестирование продукта, инспекции кода, детальное документирование процесса разработки и т.д. и т.п. Но это следовало бы назвать обеспечением качества постфактум, закономерно приводящим к необходимости борьбы с дефектами. Однако качество — это, прежде всего, соответствие программного изделия решаемой задаче. Обеспечивать качество можно и нужно путем обеспечения этого соответствия в течение всего процесса разработки. В этом случае есть шанс минимизировать количество дефектов, с которыми придется бороться. Для иллюстрации рассмотрим возможности обеспечения качества за счет организации прикладной функциональности программной системы. Совокупность реализуемых прикладных функций также называют логикой предметной области или бизнес-логикой. Организация кода, реализующего бизнес-логику, влияет на такие свойства программной системы, как расширяемость, открытость, сложность поддержки. Возможность вносить изменения в программную систему в разумные сроки и за разумные средства часто оказывается важным потребительским свойством системы. При этом вопросы организации программного кода зачастую не считаются достаточно важными, чтобы посвящать им специальные усилия архитектора (если таковой на проекте имеется), и отдаются на откуп программистам. Что отнюдь не сказывается благоприятным образом на качестве создаваемой системы. Рассмотрим вопрос рационального выбора варианта организации бизнес-логики. Наша основная цель — научиться избегать грубых ошибок за счет применения простой схемы выбора варианта. Как мы выбираем?«Святая простота»Распространенный способ выбора организации функциональности выглядит примерно следующим образом: «Почему так сделал?» — «Не знаю... я так привык...». Такой способ можно назвать «святая простота», так как выбор, в сущности, ничем не обоснован. Такая ситуация обычно складывается, если от программистов требуется, чтобы это хоть как-то заработало, а обоснованием никто не интересуется. Проблемы такого подхода очевидны. Потребительские качества программного продукта оказываются зависящими от квалификации того парня, которому выпало ваять структуру объектов или функций для приложения. Если процесс не контролировать должным образом, можно бесконечно бороться с ошибками и проблемами в продукте, связанными с неудачным выбором структуры программы. «Идеологический подход»Также распространенный, но недалеко ушедший от предыдущего способ писания программ: «Потому что правильно!». Разработчик, возможно, прочитал книгу по данной технологии и с этого момента всегда делает так, как в этой книге велено (варианты — изучил «суперуниверсальный» шаблон, скачал «рекомендуемый» пример и т.д.). Здесь личные предпочтения принимают форму твердой убежденности в «правильности» того или иного подхода. При таком подходе проблемы возникают тогда, когда технологически красивое решение оказывается не соответствующим решаемой задаче. То есть подход может работать вполне успешно, однако бездумное следование авторитетам вовсе не гарантирует от неудачных решений и низкого качества продукта в результате. Проблемы сознательного выбораВопросы организации программного кода зачастую непонятны руководителю проекта. Если «грабли» в долгосрочной перспективе менеджера не волнуют либо технологические вопросы ему вообще не интересны, то на выбор решения может элементарно не выделяться времени, как на низкоприоритетную задачу. Другая проблема — отсутствие контроля качества решения. Вопрос организации функциональности часто оказывается в компетенции отдельного программиста, пусть даже это Ведущий Разработчик. А программисту интереснее писать код, ему хочется скорее сделать работоспособную версию, пусть «кривоватую», зато будет зримый результат! Размышления о том, как оптимально сконструировать систему, чтобы минимизировать проблемы в перспективе, плохо сочетаются с желанием немедленно кодировать то, что кажется понятным. В результате разработчики начинают кодировать в соответствии с подходами, перечисленными выше. На крайний случай это называется «быстрое прототипирование» либо «наши ребята за один вечер любую задачу порвут на британский флаг». Впоследствии тем же ребятам приходится проявлять чудеса изобретательности, чтобы справиться с проблемами, возникающими из-за несоответствия архитектуры требованиям, предъявляемым к программной системе. За это программист получает отдельное спасибо, обычно заслуженное. И только он сам понимает реальную степень кривизны своего решения и осознает, что «если б было время подумать тогда, в самом начале... можно было бы так красиво сделать... а теперь уж не переделаешь...». Но на следующем проекте повторяется та же история. Попытаемся определить, как же именно можно «сделать красиво», если до начала кодирования найдется время подумать. Для этого рассмотрим типовые варианты организации бизнес-логики и предложим схему выбора варианта на основе простейших критериев. Из чего мы выбираемСуществует множество разных подходов к описанию и реализации бизнес-логики. Можно сказать, что у каждого коллектива разработчиков так или иначе формируется свой подход, что выражается в методах проектирования структуры приложения, правилах кодирования и т.д. Однако все чаще предпринимаются попытки систематизации и классификации подходов к проектированию для описания профессионального опыта в этой области. Один из способов систематизации приемов и методов проектирования структуры программных систем — шаблоны проектирования или шаблоны архитектуры (также называемые в русском переводе «паттернами», от англ. pattern — образец, модель, шаблон) [1], [2]. В частности, существует три типовых подхода к организации бизнес-логики, называемых сценарий транзакции, модель предметной области и модуль таблицы. Данные подходы в деталях рассмотрены в [1] (вплоть до фрагментов программного кода). Здесь мы рассмотрим основные особенности этих типовых решений и на их примере сформулируем соображения по выбору варианта организации бизнес-логики для проектируемой системы. Сценарий транзакции (функциональный подход)Это простейший подход к описанию бизнес-логики. За термином «сценарий транзакции» кроется функция системы, реализующая определенную функцию прикладной логики. Пример — расчет стоимости заказа, формируемого в системе. При таком подходе программная система представляет собой набор функций, в котором каждая функция соответствует операции, которую приложение выполняет для пользователя. Это старая добрая процедурная модель, хорошо известная разработчикам. Проектируется иерархия функций, возможно повторное использование функций нижних уровней. Существуют давно и хорошо отработанные методологии, а также стандарты функционального моделирования, с помощью которых можно проектировать функциональную структуру программной системы в сложных случаях. Несомненное достоинство подхода — простота реализации в программном коде. Этот вариант по плечу каждому программисту, включая новичка, едва освоившего свой первый язык программирования. Однако у функционального подхода есть и определенные недостатки. С возрастанием сложности прикладной логики становится чрезвычайно сложно формировать структуру, не содержащую дублированных функций. А попытка переделать имеющуюся сложную структуру при изменении прикладной логики быстро приводит к тому, что функциональная структура превращается в «помойку» и выходит из-под контроля разработчиков. Все это, в конечном счете, осложняет развитие и поддержку системы. Модель предметной области (объектный подход)Этот подход наиболее сложен в реализации, но и наиболее продуктивен. Разрабатывается объектная модель предметной области — по крайней мере, для основных понятий. Например, для интернет-магазина могут быть созданы объекты «клиент», «товар», «корзина», «заказ» и т.д. Вместо того, чтобы помещать бизнес-логику расчета стоимости в одну или несколько процедур, для каждого объекта реализуется функциональность исходя из зоны ответственности этого объекта. Например, объект «заказ» содержит алгоритм вычисления стоимости заказа на основе цен входящих в него товаров, при этом алгоритмы определения цен на товары реализуются отдельно, в объектах «товар». Если для разных товаров применяются разные алгоритмы вычисления цены, это достаточно легко реализовать в модели за счет создания разных типов товаров. Достоинством модели предметной области традиционно признается гибкость. Объектный подход предоставляет в распоряжение разработчика множество способов моделирования отношений и распределения ответственности между объектами, что позволяет настраивать бизнес-логику в очень широких пределах. Кроме того, важной особенностью объектного подхода является то, что объекты могут близко соответствовать понятиям прикладной области, что в принципе позволяет разработчику и заказчику «говорить на одном языке». Еще одним доводом в пользу объектного моделирования является то, что подавляющее большинство типовых решений — шаблонов проектирования — создано именно для применения в объектной модели. Шаблоны позволяют разрабатывать объектные структуры с заданными свойствами. В частности, создатели шаблонов уделяют значительное внимание последствиям применения шаблонов и возможностям внесения изменений в объектные структуры, предлагаемые шаблонами. Однако за все приходится платить. В случае объектного подхода за исключительную гибкость приходится платить необходимостью выработки определенного, своеобразного стиля мышления. Новичкам приходится затрачивать много времени даже на то, чтобы разобраться в имеющейся объектной структуре (например, в шаблоне), не говоря уже о самостоятельном проектировании объектной структуры. Не всем удается преодолеть барьер освоения этой технологии; многие разработчики, даже работая на объектно-ориентированном языке и применяя объектные библиотеки, фактически используют процедурный стиль программирования. Другая особенность модели предметной области — необходимость создания сложных программных механизмов взаимодействия объектных структур с реляционными базами данных. Разработка такого механизма обычно обходится дорого (хотя на этот счет тоже имеются типовые решения), и это, конечно, не упрощает жизнь в случае применения объектной модели. Модуль таблицы (смешанный подход)Перечисленные выше методы организации бизнес-логики представляют собой два «крайних» случая. Третий случай — смешанный, гибридный подход, сочетающий в себе определенные достоинства (и недостатки) функционального и объектного подходов. Типовое решение «модуль таблицы» предусматривает, как и в модели предметной области, отдельные объекты для товаров, заказов и т.д. Однако, в отличие от «настоящей» модели предметной области, в модуле таблицы для работы со всеми (к примеру) заказами, содержащимися в базе данных, применяется только один объект. Именно этот единственный объект содержит логику обработки заказов. А чтобы работать с отдельным заказом, следует указывать его уникальный идентификатор. Перечитайте предыдущий абзац. Вас не пугает то, что в нем написано? И вам все понятно? Тогда, скорее всего, для вас не будет иметь значения недостаток данного подхода — сложность разработки и сложность восприятия кода. С точки зрения прозрачности, читабельности кода модуль таблицы заметно проигрывает «настоящей» модели предметной области (конечно, предполагается, что разработчик в каждом случае использует максимум возможностей сделать код простым и понятным). При несложной логике предметной области модуль таблицы проигрывает в простоте реализации и функциональному подходу. Основные преимущества модуля таблицы — простота взаимодействия с базой данных и гибкость структурирования бизнес-логики по сравнению с функциональным подходом. Возможно также применение шаблонов проектирования. Однако по сравнению с моделью предметной области гибкость и возможности применения шаблонов в модуле таблицы существенно ограничены. Целесообразность применения модуля таблицы также зависит от уровня поддержки структуры множества записей в конкретной среде разработки (включая удобство отображения множества записей на базу данных и на элементы графического интерфейса). Развитая поддержка набора данных ( DataSet ) в среде Microsoft . Net во многих случаях оправдывает применение этой платформы разработки. Что мы выбираемОсобенности подходовПеречислим основные особенности рассмотренных типовых решений, позволяющие сравнивать эти решения между собой и выбирать подход, соответствующий задаче. Сценарий транзакции (функциональный подход) : предельно прост, плохо работает при сложной логике, затрудняет развитие системы. Модель предметной области (объектный подход) : наиболее сложный и затратный, позволяет реализовать сложную бизнес-логику, дает возможность «цивилизованно» развивать систему; для простых систем подход целесообразен, только если уже «обкатан» разработчиком. Модуль таблицы (смешанный подход) : обеспечивает определенное сочетание простоты и гибкости, однако гибкость ограничена, а эффективность подхода зависит от среды разработки. На основе рассмотренных особенностей можно сформулировать несколько критериев и предложить упрощенную схему выбора подхода на основе качественной оценки критериев. Качественные критерии и схема выбораОсобенности типовых решений показывают, что решение по выбору подхода можно принять на основе качественной оценки следующих критериев:
Схема принятия решения на основе этих критериев приведена на рисунке. Упрощенная схема выбора типового решения для реализации бизнес-логики На схеме хорошо видно, что в некоторых случаях выбор сделать очень легко. Например, когда приложение простое, изменений не предвидится, да и с объектной моделью связываться непривычно — с чистой совестью применяем простой функциональный подход. С другой стороны, команда фанатов объектного подхода будет строить объектную модель предметной области во всех случаях — и правильно сделает (учитывая то, что такая команда вряд ли будет заниматься тривиальными проектами). Пограничные ситуации требуют оценки стабильности и сложности разработки. На предлагаемом уровне это не должно вызвать затруднений. Данная методика предназначена в первую очередь для оперативного «прокручивания» в голове с целью избежать грубых ошибок при выборе программного решения. Подобная систематизация также представляется полезной как первый шаг программиста к сознательному и ответственному проектированию приложений, в противоположность «проектированию на лету». В реальных проектах, как обычно, все обстоит сложнее. Например, вопрос организации бизнес-логики может теряться на фоне массы других вопросов разработки архитектуры. Однако это не значит, что решение нужно пускать на самотек. Приведенная схема показывает, что можно предельно упростить принятие решения, не теряя при этом возможность выявить «подводные камни». ВкратцеРешение по организации прикладной логики программной системы непосредственно влияет на качество создаваемого изделия. Это решение может и должно приниматься сознательно, исходя из требований и применяемых технологий. В идеале при выборе программного решения следует учитывать гораздо больше факторов, чем мы здесь упоминаем. Однако использование предлагаемой схемы выбора может стать первым шагом к формированию привычки выбирать обоснованное решение по организации бизнес-логики. Существует три основных способа организации бизнес-логики программной системы: функциональный, объектный и смешанный. Каждый из способов имеет свои преимущества и недостатки, и задача разработчика — выбрать способ, оптимальный для данного проекта. В первом приближении выбор решения можно предельно упростить, однако в каждом конкретном проекте существует множество «подводных камней», для выявления которых может понадобиться весь богатый опыт «хождения по граблям». Единственное, чего не следует делать — это бездумно полагаться при выборе программной конструкции на личные пристрастия или мнения авторитетов. Начните с простых правил, применяйте проверенные шаблоны, рассматриваемые в профессиональной литературе, но в любом случае выбирайте решение самостоятельно. Литература
Игорь Остроухов, Tags: |