Понятия связанности (Coupling) и зацепления (Cohesion) в сложных программных системах. Связанность и зацепление классов, модулей, компонентов

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

- Изменения в связанных классах приводят к локальным изменениям в данном классе.

- Затрудняется понимание каждого класса в отдельности.

- Усложняется повторное использование, поскольку для этого требуется дополнительный анализ классов, с которыми связан данный класс.

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

- Изменения компонентов мало сказываются на других объектах.

- Принципы работы и функции компонентов можно понять, не изучая другие объекты.

- Удобство повторного использования.

Зацепление (cohesion) (функциональное зацепление) – это мера связанности и сфокусированности обязанностей класса. Считается, что элемент обладает высокой степенью зацепления, если его обязанности тесно связаны между собой и он не выполняет непомерных объёмов работы. В роли таких элементов могут выступать классы, подсистемы и т.д.

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

- Трудность понимания.

- Сложность при повторном использовании.

- Сложность поддержки.

- Ненадёжность, постоянная подверженность изменениям.

Классы со слабым зацеплением, как правило, являются слишком «абстрактными» или выполняют обязанности, которые можно легко распределить между другими объектами.

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

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

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

Ещё одной особенностью, тесно связанной со связыванием и зацеплением, является модульность. Модульность – это свойство системы, разбитой на множество модулей с высокой степенью зацепления и слабым связыванием.

40. Ошибки программирования: переполнение буфера. Понятие безопасного программного кода.

Переполнение буфера это проблема, характерная для языков 3-го поколения. Смыл проблемы заключается в том, что программа может записать данные за пределы выделенного в памяти буфера, что может привести к дальнейшим ошибкам в работе программы. Различают два основных варианта переполнения: “сверху” (overrun) и “снизу” (underrun). Оба варианта могут иметь место на организации буфера в виде “стека” или “кучи”.

Рассмотрим принцип появления проблемы на примере переполнения “сверху” в стеке. Регистр ESP указывает на вершину стека. При вызове некоторой подпрограммы, он, как правило, будет указывать на адрес кода возврата. Допустим, что при вызове данной подпрограммы необходимо передать в качестве параметра строку длиной 10 символов. Однако, при передаче было передано большее количество символов (например 12). Компилятор выделит в стеке 10 байт памяти под массив символов. Соответственно, адрес возврата сместится вглубь стека, и за ним встанет выделенный объем памяти. В момент передачи параметра, первые 10 символов запишутся в выделенный объем памяти, а оставшиеся 2 байта затрут в стеке значение адреса кода возврата. Т.о., значение адреса кода возврата изменится. По окончанию работы подпрограммы, сначала из стека выгрузятся (уничтожаться) все выделенные раннее структуры памяти. Так, адрес возврата снова “спустится” к выходу из стека, и регистр ESP будет указывать именно на него. Однако, значение было изменено. Компилятор интерпретирует его уже как другой адрес и сделает по нему возврат, что и будет составлять главную проблему.

Такая ошибка типична, и часто используема. Существуют случаи, преднамеренного использования такой ошибки в целях НСД, нарушения данных и т.д. Вызов методов подстраивался таким образом, чтобы по окончанию их работы, управление передавалось на другие вредоносные программы или вызов WinApi методов (создание нового администратора, наделение пользователя Guest администраторскими правами и т.д.).

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

Безопасный программный код – это программный код, написанный с использованием методов безопасного программирования.

Наши рекомендации