Как стать автором
Обновить

Десять рекомендаций разработчику программного обеспечения

Время на прочтение6 мин
Количество просмотров2.8K
Разработка комплексных программных систем сопряжена со значительными трудностями, обусловленными необходимостью:
a) быстрого создания прототипа системы,
b) обеспечения качества ее модели и исходных кодов,
с) внесения изменений в течение жизни системы.

Далее приведены десять рекомендаций, которые помогут разработчикам на их трудном пути создания комплексных систем.


1. Используйте мощь современных платформ разработки программного обеспечения

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

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

2. Отнеситесь со всей серьезностью к проектированию приложения

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

Об успешности будущего проекта можно косвенно судить по количеству раз, когда на этапе проектирования и реализации были произнесены фразы «сейчас сделай так, а потом, если что, переделаем» (больше – хуже) и «этот блок функциональности мы потом как захотим, так и реализуем» (больше – лучше). Почему? Потому, что в первом случае было сделано явное предположение о том, как должен работать блок функциональности, и причем, работать в режиме «костыля». А во втором случае решение о конкретной реализации было отложено на этап, когда будет понятно, как она должна выглядеть.

3. Используйте наследование объектов предметной области и пользовательского интерфейса

При использовании наследования Вы сможете задать «в одном месте» общее поведение для группы объектов вашей системы.

Для объектов предметной области наследование Вам поможет при определении общих атрибутов и функциональности объектов.

Для пользовательского интерфейса наследование будет полезным при определении общих компонентов экранных форм (будь то win или web-формы).

В качестве примера наследования представлений рассмотрим форму абстрактного архива (т.е. списка) документов. В соответствии с иерархией наследования бизнес-объектов, абстрактный документ имеет 2 предопределенных атрибута «Номер» и «ДатаДокумента». Нарисуем форму абстрактного архива документов и поместим на нее таблицу («грид») с двумя столбцами: «Номер» и «Дата». Укажем в верхней части формы компонент управления глубиной просмотра архива (изначальный отбор записей по дате документа) и настроим кнопки контекстного меню таблицы.

Далее, определим объект «Кадровый Документ», который унаследован от «Абстрактный Документ». В дополнение к полям «Номер» и «Дата документа» у нового объекта будет поле «Сотрудник». При этом Вам не надо “рисовать” экранную формы для нового архива. Вы указываете форму абстрактного архива в качестве базовой для формы нового архива, добавляете в существующую таблицу столбец «Сотрудник» и связываете этот столбец с данными. Вся функциональность формы (например, глубина просмотра) будет унаследована и автоматически реализована в архиве кадровых документов. Сокращение времени разработки очевидно.

4. Разделяйте бизнес-логику приложения и интерфейс пользователя

Выполнение данного условия фактически означает появление «контракта» взаимодействия между GUI и бизнес-логикой. При этом Вы сможете не только снабдить вашу систему несколькими интерфейсами пользователя (например, win и web), но и реализовать защищенные и понятные интерфейсы для классов бизнес-логики.

Этот «контракт» поможет Вам в дальнейшем при внесении существенных изменений в модель системы.

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

Это основной принцип объектно-ориентированного подхода к разработке программного обеспечения. Вы пишите классы для объектов предметной области и заставляете их обмениваться сообщениями (вызывать открытые методы друг у друга). Таким образом достигается необходимая функциональность системы.

Например Вам необходимо в экранной форме при нажатии кнопки «OK» сохранить редактируемый объект в базе данных. Код вашего обработчика нажатия кнопки должен выглядеть так:

{
РедактируемыйОбъект.Сохранить();
}

Метод Сохранить() в себе содержит все необходимые проверки корректности объекта, генерации соответствующего события объекта и передачи управления менеджеру базы данных параметров сохранения. То есть объект экранной формы посылает связанному бизнес-объекту сообщение с сигнатурой «Сохранить».

А если в указанном примере Вы вынесете проверку корректности объекта в метод экранной формы, то такой код в дальнейшем Вам будет трудно контролировать. Особенно если у объекта будет несколько форм редактирования.

6. Инкапсулируйте функциональность Вашей системы в объекты, компоненты и подсистемы

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

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

7. Используйте четкие, понятные и естественные интерфейсы для описания возможностей взаимодействия между компонентами и подсистемами вашего приложения.

Интерфейсы являются связующим звеном между компонентами системы. Доработки компонента, которые не меняют его интерфейс-взаимодействия, не отражаются на работе системы в целом и не требуют комплексного интеграционного тестирования системы.

Таким образом, основная цель разработчика – это снабдить свой компонент таким интерфейсом, чтобы он оставался неизменным как можно дольше в процессе доработки системы. Если этот интерфейс не будет четким, понятным и естественным, то с большой вероятностью он будет изменен в самое ближайшее время (см. Совет 2).

8. Пишите автоматические тесты для проверки корректности реализации функциональности системы

Автоматические тесты помогают разработчику понять правильно ли работает его компонент. Каждый тестовый сценарий отвечает за проверку отдельного элемента интерфейса компонента (так называемый unit test). Для написания таких тестов существует открытая разработка NUnit.

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

В некоторых случаях, тестовый драйвер компонента рекомендуется написать до разработки функциональности самого компонента (по набору случаев использования). Этим Вы поможете себе в разработке «правильного» интерфейса компонента.

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

9. Используйте инструментальные средства автоматической генерации кода

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

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

10. Помните, что база данных – это не цель, а средство

При выборе того, какой сервер базы данных использовать для вашей системы, необходимо оценивать не простоту написания кода для взаимодействия с ним, а его безопасность, быстроту работы, сохранность данных и другие параметры. По крайней мере, «обертки» для выполнения операций взаимодействия с вашей СУБД Вы сможете написать, а вот изменить поведение самого сервера – нет.

Так же необходимо подходить к вопросу написания хранимых процедур для выполнения операций с сервером СУБД. Нет смысла всю бизнес-логику системы писать в виде хранимых процедур. В этом случае Вы не сможете эффективно использовать объектно-ориентированный подход к разработке системы и распределить вычислительные мощности между компьютерами локальной сети. В хранимые процедуры имеет смысл выносить только действительно «тяжелые» обработки, затрагивающие большой объем данных.
Теги:
Хабы:
Всего голосов 28: ↑22 и ↓6+16
Комментарии18

Публикации