Существенной чертой индустриально организованных программных систем является их большая сложность. Фактически невозможно охватить все тонкости системы одним человеком. Сложность таких систем превышает возможности человеческого интеллекта.
Сложность ПО определяется четырьмя основными причинами:
1.Сложность проблемы.
А) Трудность понимания.
Б) Дополнительные требования. (Удобство,Цена,Надежность)
В) Несовместимость областей знания.
Г) Изменение требований.
Д) Эволюция системы.
2.Сложность управления процессом разработки.
А) Рост числа строк программного кода.
Б) Необходимость в коллективной разработке.
В) Необходимость в координации и согласовании работ отдельных исполнителей.
Г) Целостность основной идеи.
3.Сложность обеспечения гибкости программному продукту.
4.Сложность описания поведения отдельных подсистем.
А) Предсказуемость поведения аналоговых систем.
Б) Дискретность программных систем.
В) Большое количество переменных, их значений, адресов, стеков.
Г) Комбинаторный взрыв.
Д) Стремление к независимости подсистем.
Е) Тестирование.
Пять признаков сложной системы
1. Сложность часто представляют в виде иерархии.
2. Выбор низшего уровня абстракции достаточно произволен и в большей степени определяется наблюдателем.
3. Внутриэлементные связи обычно сильнее межэлементных.
4. Иерархические подсистемы обычно состоят из нескольких подсистем разного типа, реализованных в различном порядке в разнообразных комбинациях.
5. Работающая сложная система неизбежно оказывается результатом развития работающей простой системы.
Каноническая форма сложной системы
Сложные системы содержат много разных иерархий. Например: в самолете можно выделить системы силовой установки, системы управления самолетом и т.д. Такое разбиение дает структурную иерархию — это часть того. Есть другая форма иерархии. Например: турбореактивный двигатель — это особый тип реактивного двигателя. Это так называемая типовая иерархия.
В канонической форме сложной системы типовой иерархии сопоставляется структура классов, а структурной иерархии структура объектов.
Декомпозиция
Способ управления сложными системами был известен еще в древности. При проектировании сложной программной системы ее надо составлять из небольших подсистем, каждую из которых можно отладить независимо от других.
Алгоритмическая декомпозиция
Здесь используется структурное проектирование по методу сверху вниз. Мы выделяем алгоритмы, каждый из которых выполняет один из важных этапов общего процесса.
ОО декомпозиция
В этом случае мир представлен списком автономных действующих лиц, которые взаимодействуют друг с другом, чтобы обеспечить поведение системы соответствующее более высокому уровню. Каждый объект нашей системы обладает своим собственным поведением, моделирующим поведение реального объекта. Объекты производят действия, и мы поручаем им сделать что-то посылая им сообщение. Т.к. наша декомпозиция основана на объектах, а не на алгоритмах, то мы называем ее объектной декомпозицией.
Объектный подход
I поколения — приближение к предметной области.
II поколения — развитие алгоритмической абстракции.
III поколения — обработка абстрактных данных, модульная структура программы.
Суть абстрагирования достигаемого посредством использования процедур достаточна для описания абстрактных действий, но не достаточна для описания абстрактных объектов. Это серьезный недостаток т.к. во многих практических ситуациях сложность объектов являющихся предметом управления составляет основную часть сложности всей задачи. Из этого вытекает два важных следствия. Во-первых, возникают методы проектирования управляемыми данными, которые вносят порядок в обработку абстрактных данных алгоритмическими языками. Во-вторых, появляется теория типирования, которая воплощается в языках типа PASCAL. Если представить процедуры и функции в виде глаголов, а данные в виде имен существительных, то процедурные программы строятся из глаголов, а объектно-ориентированные из имен существительных. Естественным завершением реализации этих идей стало появление объектно-ориентированных языков, таких как C++, SMALLTALK, CLOS, ADA, и т.д.
Данные и действия в этих языках организуются т.о., что основой конструкции становятся классы и объекты, а не алгоритмы.
Рассмотрим четыре главных элемента ОП:
1. Абстрагирование. Является одним из основных способов используемых для решения сложных задач. Абстракция — это такие существенные характеристики некоторого объекта, которые отличают его от всех других видов объекта и т.о. четко определяют особенности данного объекта с точки зрения его дальнейшего рассмотрения и анализа. Абстрагирование концентрирует внимание на внешних особенностях объекта и позволяет отделить самые существенные особенности поведения от деталей их осуществления. Такое отделение называется барьером абстракции, который основывается на принципе минимизации связи. Когда интерфейс объекта содержит только существенные аспекты поведения. Выбор достаточного множества абстракций для заданной предметной области является главной проблемой ООП.
2. Ограничение доступа. Введению абстракций какого-либо объекта должны сопутствовать определенные решения о способе ее реализации. Выбранный способ реализации должен быть скрыт и защищен для большинства объектов пользователей обращающихся к данной реализации. Никакая часть сложной системы не должна находиться в зависимости от подробностей внутреннего устройства других частей системы. Для работы абстракции доступ к ее внутренней структуре должен быть ограничен. Практически это означает наличие двух частей в описании класса: интерфейс, реализация. Интерфейс отражает внешнее проявление объекта, создавая абстракцию поведения всех объектов данного класса. Внутренняя реализация описывает механизмы достижения желаемого поведения объекта.
3. Модульность. Разделение программы на фрагменты позволяет частично уменьшить ее сложность, однако гораздо больше важен тот факт, что разделение программы улучшает проработку ее частей. Эти части очень полезны для исчерпывающего понимания программы в целом. Правильное разделение программы является почти такой же сложной задачей, как и выбор правильного набора абстракций. Модули выполняют роль физических контейнеров в которые помещаются определения классов и объектов. Конечной целью декомпозиции программы на модули является снижение затрат на программирование за счет независимой разработки и тестирования. Приемы эффективной декомпозиции: а) структура модуля должна быть достаточно простой для восприятия; б) реализация каждого модуля не должна зависеть от реализации других модулей; в) должны быть приняты меры для внесения изменений там, где они наиболее вероятны; г) перекомпиляция тела модуля нетрудоемкая, интерфейсной части наоборот.
Поэтому необходимо стремиться к тому, чтобы интерфейсная часть модулей была, возможно, более узкой. Т.о. принципы абстрагирования, ограничения доступа и модульности являются взаимодополняющими. Объект определяет явные границы определенной абстракции, а ограничение доступа и модульность создают барьеры между абстракциями. Вычленение классов и объектов проекте, а так же организация модульной структуры — существенно независимые решения. Процесс вычленения составляет часть процесса логического проектирования системы, а деление на модули — этап физического проектирования.
4. При большом числе абстракций необходимо использовать механизм помогающий упростить проектирование сложных систем. Такой механизм — иерархия. Иерархия — это ранжированная или упорядоченная система абстракций.
