Объектно-ориентированное программирование

Лекция 5. Конструирование программ. Структурное программирование

Одной из основных задач проектирования является декомпозиция системы,

т. е. разделение системы в целом на совокупность взаимосвязанных элементов. При декомпозиции последовательно меняется уровень детализации системы.

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

При нисходящем проектировании (проектировании «сверху вниз») проектирование начинается с верхнего уровня. Система иерархически разбивается на подсистемы и т.д. вплоть до компонентов нижнего уровня. Это метод общего назначения, с его помощью можно проектировать любую систему.

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

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

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

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

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

Абстрагирование — выделения абстракций (abstraction), под которыми понимаются существенные характеристики объекта, которые отличают его от всех других объектов и четко определяют его концептуальные границы для наблюдателя.

Инкапсуляция (encapsulation) — разделение элементов абстракции, которые образуют ее структуру и поведение.

Модульность (modularity) — разделение системы на модули (module), под которыми понимаются единицы кода, служащие блоками физической структуры системы.

Иерархия (hierarchy) — подчинение или упорядочение абстракций. Две типичных иерархии в сложной системе — иерархия наследования «общее/частное», присущая, обычно, типам (классам) и иерархия агрегирования «целое/часть», присущая, обычно, элементам (объектам). Иерархия присуща также модулям и другим частям системы.

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

Для ООП характерны понятия наследования и полиморфизма.

Наследование (inheritance) — отношение между классами, при котором класс использует структуру или поведение другого (одиночное наследование) или других (множественное наследование). Наследование вводит иерархию «общее/частное».

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