Чтение онлайн

на главную - закладки

Жанры

Программист-прагматик. Путь от подмастерья к мастеру
Шрифт:

Рассмотрим сложную систему контроля и управления отопительной установкой. Первоначально требовалось наличие графического интерфейса, но затем требования были изменены, с тем чтобы добавить систему речевого ответа и управления установкой при помощи телефона с тональным набором. В ортогонально спроектированной системе для этого вам пришлось бы изменить только модули, связанные с интерфейсом пользователя, а основная логика управления предприятием остается неизменной. На самом деле, если вы тщательно структурируете систему, то у вас должна быть возможность поддержки обоих интерфейсов при наличии одной и той же программной базы. В разделе "Всего лишь представление" говорится о написании программ, в которых отсутствует связанность, используя парадигму "модель-представление-контроллер" (Model-View-Controller), подходящую в данной ситуации.

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

Инструментарии и библиотеки

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

Однажды авторы работали над проектом, в котором требовалось, чтобы некий фрагмент программы на языке Java выполнялся автономно – на сервере и в удаленном режиме – на клиентской машине. В этом случае возможными вариантами распределения классов были технологии RMI и CORBA. Если удаленный доступ к классу обеспечивался при помощи RMI, то в этом случае каждое обращение к удаленному методу в этом классе могло бы привести к генерации исключения, означающей, что эта наивная реализация потребовала бы от нас обработки этого исключения всякий раз при использовании удаленных классов. В данном случае использование RMI явно не ортогонально: программа, обращающаяся к удаленным классам, не должна зависеть от их физического расположения. Альтернативный способ – технология CORBA – не налагает подобного ограничения: мы можем написать программу, для которой не имеет значения, где физически находятся классы.

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

Интересным примером ортогональности является система Enterprise Java Beans (EJB). В большинстве диалоговых систем обработки запросов прикладная программа должна обозначать начало и окончание каждой транзакции. В системе EJB эта информация выражена описательно в виде метаданных вне любых программ. Та же самая прикладная программа может работать в различных транзакционных средах EJB без каких-либо изменений. Вероятно, это станет прообразом многих операционных сред будущего.

Другой интересной проверкой на ортогональность является технология Aspect-Oriented Programming (АОР) – исследовательский проект фирмы Xerox Pare ([KLM+97] и [URL 49]). Технология АОР позволяет выразить в одном-единственном месте линию поведения, которая в противном случае была бы распределена по всему исходному тексту программы. Например, журнальные сообщения обычно генерируются путем явных обращений к некоторой функции записи в журнал по всему исходному тексту. Используя технологию АОР, вы реализуете процедуру записи в журнал ортогонально к записываемым данным. Используя версию АОР для языка Java можно записать сообщение журнала при входе в любой метод класса Fred, запрограммировав аспект:

aspect Trace {

 advise * Fred.*(…) {

static before {

Log.write("-» Entering " + thisJoinPoint.methodName);

}

}

}

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

Написание текста программы

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

Есть ряд методик, которые можно использовать для поддержки ортогональности:

• Сохраните вашу программу «несвязанной». Напишите «скромную» программу – модули, которые не раскрывают ничего лишнего для других модулей и не полагаются на их внедрение. Попробуйте применить закон Деметера [LH89], который обсуждается в разделе "Несвязанность и закон Деметера". При необходимости изменения состояния объекта это должен делать сам объект. В таком случае программа остается изолированной от реализации другой программы, а вероятность того, что система останется ортогональной, увеличивается.

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

Шаблон Singleton, упомянутый в книге "Design Patterns" [GHJV95], представляет собой способ подтвердить существование единственного представителя объекта определенного класса. Многие используют эти объекты типа Singleton как своего рода глобальную переменную (особенно при работе с языками типа Java, которые иначе не поддерживают технологию глобальных переменных). Будьте внимательны с шаблонами Singleton – они также могут приводить к ненужному связыванию.

• Подобные функции. Зачастую вы сталкиваетесь с набором функций, похожих друг на друга; возможно, они используют общий фрагмент в начале и конце программы, но в ее середине каждая пользуется своим алгоритмом. Дублированная программа является признаком структурных проблем. Для того чтобы составить программу лучше, следует обратить внимание на шаблон Strategy в книге "Design Patterns".

Пусть постоянное критическое отношение к вашей программе войдет у вас в привычку. Ищите любые возможности реорганизации для усовершенствования ее конструкции и повышения уровня ортогональности. Этот процесс называется реорганизацией, и он важен настолько, что в книге ему посвящен целый раздел (см. "Реорганизация").

Тестирование

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

Поделиться:
Популярные книги

Ермак. Регент

Валериев Игорь
10. Ермак
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Ермак. Регент

Ученик. Книга 4

Первухин Андрей Евгеньевич
4. Ученик
Фантастика:
фэнтези
5.67
рейтинг книги
Ученик. Книга 4

Геном хищника. Книга девятая

Гарцевич Евгений Александрович
9. Я - Легенда!
Фантастика:
боевая фантастика
рпг
попаданцы
5.00
рейтинг книги
Геном хищника. Книга девятая

Вечный. Книга V

Рокотов Алексей
5. Вечный
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Вечный. Книга V

Технарь

Муравьёв Константин Николаевич
1. Технарь
Фантастика:
космическая фантастика
попаданцы
7.13
рейтинг книги
Технарь

#Бояръ-Аниме. Газлайтер. Том 37

Володин Григорий Григорьевич
37. История Телепата
Фантастика:
фэнтези
аниме
боевая фантастика
5.00
рейтинг книги
#Бояръ-Аниме. Газлайтер. Том 37

Снега

Чепурин Юлий Петрович
Поэзия:
драматургия
5.00
рейтинг книги
Снега

Черный Маг Императора 19

Герда Александр
19. Черный маг императора
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Черный Маг Императора 19

Дважды одаренный. Том IV

Тарс Элиан
4. Дважды одаренный
Фантастика:
городское фэнтези
альтернативная история
аниме
7.00
рейтинг книги
Дважды одаренный. Том IV

Я не князь. Книга XIII

Дрейк Сириус
13. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я не князь. Книга XIII

Неверный

Тоцка Тала
Любовные романы:
современные любовные романы
5.50
рейтинг книги
Неверный

Как прорастают зерна

Волкова Дарья
Любовные романы:
современные любовные романы
7.00
рейтинг книги
Как прорастают зерна

Наследие Маозари 8

Панежин Евгений
8. Наследие Маозари
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
постапокалипсис
рпг
фэнтези
эпическая фантастика
5.00
рейтинг книги
Наследие Маозари 8

Низший - Инфериор. Компиляция. Книги 1-19

Михайлов Дем Алексеевич
Фантастика 2023. Компиляция
Фантастика:
боевая фантастика
5.00
рейтинг книги
Низший - Инфериор. Компиляция. Книги 1-19