Добавить в корзинуПозвонить
Найти в Дзене
Physics.Math.Code

Эвристические принципы проектирования ПО

● Стремитесь к максимальной связности Понятие связности (cohesion) возникло в области структурного проектирования и обычно обсуждается в том же контексте, что и сопряжение (coupling). Связность характеризует то, насколько хорошо все методы класса или все фрагменты метода соответствуют главной цели, — иначе говоря, насколько сфокусирован класс. Классы, состоящие из очень похожих по функциональности блоков, обладают высокой степенью связности, и наша эвристическая цель состоит в том, чтобы целостность была как можно выше. Связность — полезный инструмент управления сложностью, потому что чем лучше код класса соответствует главной цели, тем проще запомнить все, что код выполняет. Стремление к связности на уровне методов давно считается полезным эвристическим принципом. На уровне классов эвристический принцип связности во многом выражен в более общем эвристическом принципе адекватного определения абстракций, что уже обсуждалось в этой главе и будет еще обсуждаться в главе 6. Абстрагировани
Оглавление

● Стремитесь к максимальной связности

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

Стремление к связности на уровне методов давно считается полезным эвристическим принципом. На уровне классов эвристический принцип связности во многом выражен в более общем эвристическом принципе адекватного определения абстракций, что уже обсуждалось в этой главе и будет еще обсуждаться в главе 6. Абстрагирование полезно и на уровне методов, но в этом случае принципы абстрагирования и связности более равноправны.

● Формируйте иерархии

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

Формирование иерархий уже более 2000 лет является важным средством управления сложными наборами информации. Так, Аристотель использовал иерархию для организации царства животных. Люди часто организуют сложную информацию (такую как эта книга) при помощи иерархических схем. Ученые обнаружили, что люди в целом находят иерархии естественным способом организации сложной информации. Рисуя сложный объект (скажем, дом), люди рисуют его иерархически. Сначала они рисуют очертания дома, затем окна и двери, а после этого — еще более подробные детали. Они не рисуют дом по отдельным кирпичам, доскам или гвоздям (Simon, 1996).

Иерархии помогают в достижении Главного Технического Императива Разработки ПО, позволяя сосредоточиться только на том уровне детальности, который заботит вас в конкретный момент. Иерархия не устраняет детали — она просто выталкивает их на другой уровень, чтобы вы могли думать о них, когда захотите, а не все время.

● Формализуйте контракты классов

На более детальном уровне полезную информацию можно получить, рассматривая интерфейс каждого класса как контракт с остальными частями программы. Обычно контракт имеет форму «Если вы обещаете предоставить данные x, y и z и гарантируете, что они будут иметь характеристики a, b и c, я обязуюсь выполнить операции 1, 2 и 3 с ограничениями 8, 9 и 10». Обещания клиентов классу обычно называются
предусловиями (preconditions), а обязательства класса перед клиентами —постусловиями (postconditions).
Контракты помогают управлять сложностью, потому что хотя бы теоретически объект может свободно игнорировать любое поведение, не описанное в контракте. На практике этот вопрос куда сложнее.

● Грамотно назначайте сферы ответственности

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

● Проектируйте систему для тестирования

На некоторые интересные идеи можно натолкнуться, спросив, как будет выглядеть система, если спроектировать ее для обеспечения максимальной легкости тестирования. Отделять ли пользовательский интерфейс от остальной части программы, чтобы протестировать его независимо? Организовывать ли каждую подсистему так, чтобы минимизировать ее зависимость от других подсистем? Проектирование для тестирования часто приводит к разработке более формализованных интерфейсов классов, что обычно выгодно.

● Избегайте неудач

Профессор гражданского строительства Генри Петроски в интересной книге «Design Paradigms: Case Histories of Error and Judgment in Engineering» (Petroski, 1994), посвященной истории неудач в отрасли проектирования мостов, утверждает, что многие известные мосты рушились из#за чрезмерного внимания к прошлым успехам и неадекватного рассмотрения возможных причин аварий. Он делает вывод, что аварий вроде крушения моста Tacoma Narrows можно было бы избежать, если б инженеры тщательно рассматривали возможные причины аварий, а не просто копировали другие успешные проекты.

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

● Тщательно выбирайте время связывания

Временем связывания (binding time) называют тот момент, когда переменной присваивается конкретное значение. Раннее связывание обычно упрощает код, но и снижает его гибкость. Иногда к полезным идеям проектирования можно прийти, спросив себя: «Что, если связать эти значения раньше? Что, если связать их позже? Что, если инициализировать эту таблицу в этом месте кода? Что, если получить значение этой переменной от пользователя в период выполнения программы?»

● Создайте центральные точки управления

Ф. Дж. Плоджер говорит, что главным его принципом является «Принцип Одного Верного Места: в программе должно быть Одно Верное Место для поиска нетривиального фрагмента кода и Одно Верное Место для внесения вероятных изменений» (Plauger, 1993). Управление может быть централизовано в классах, методах, макросах препроцессора, файлах, включаемых директивой #include, — даже именованная константа может быть центральной точкой управления.
Этот принцип также способствует снижению сложности: если какой
-то программный элемент встречается в минимальном числе фрагментов, его изменение окажется проще и безопаснее.

● Подумайте об использовании грубой силы

Грубая сила — один из мощнейших эвристических инструментов. Не стоит ее недооценивать. Работоспособное решение проблемы методом грубой силы лучше, чем элегантное, но не работающее решение. Создавать элегантные решения зачастую долго и сложно. Так, описывая историю разработки алгоритмов поиска, Дональд Кнут указал, что, хотя первое описание алгоритма двоичного поиска было опубликовано в 1946 г., алгоритм, правильно обрабатывающий списки всех размеров, был разработан только спустя 16 лет (Knuth, 1998). Двоичный поиск элегантнее, но и основанный на грубой силе последовательный поиск часто приемлем.

● Рисуйте диаграммы

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

● Поддерживайте модульность проекта системы

Этот принцип подразумевает, что каждый метод или класс должен быть похож на «черный ящик»: вы знаете, что в него поступает и что из него выходит, но не знаете, что происходит внутри. Черный ящик имеет такой простой интерфейс и такую ясную функциональность, что для любых конкретных входных данных можно точно предсказать соответствующие выходные данные. Концепция модульности связана с сокрытием информации, инкапсуляцией и другими эвристическими принципами проектирования. И все же размышление о том, как собрать систему из набора черных ящиков иногда приводит к догадкам, к которым сокрытие информации и инкапсуляция привести не могут, так что принцип модульности заслужил право занять место в вашем арсенале полезных идей.

Резюме эвристических принципов проектирования

Ниже приведен список основных эвристических принципов проектирования:

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

Следующие эвристические принципы также иногда бывают полезны:

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

Скачать все книги в telegram
https://t.me/physics_lib
https://tlgg.ru/physics_lib
https://tgtg.su/physics_lib
https://telete.in/physics_lib
https://ttttt.me/physics_lib

Physics.Math.Code в контакте (VK)

Physics.Math.Code в telegram

Physics.Math.Code в YouTube

Репетитор IT mentor в VK

Репетитор IT mentor в Instagram