понедельник, 29 июля 2013 г.

ПМО ИУС — ООП — Инкапсуляция и модульность

Инкапсуляция хорошо по интуитивному смыслу дружит с модульностью, поэтому благоразумно давать их вместе — первое как контроль состояния объекта и защита от внешних воздействий, и модульность как уменьшение сложности методом распиливания на независимые части. В рамках первой — это перевод всех данных под private раз и навсегда до конца курса, в рамках второй — разделение класса на пару файлов hpp/cpp и вынесение их в отдельное место, отличное от главной программы, которая уже подключает их через include.

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

С точки зрения работы функционал практически не добавляется — только с точки зрения поведения классов необходимо добавить действия по сохранению объекта в корректном состоянии (чтобы Дюймовочка не плыла участки в минус 5 метров, иначе поведение объекта или его состояние может стать некорректным) — это делается как раз вместе с инкапсуляцией. Кроме того, идет разделение и вынос hpp/cpp, что тоже не меняет функционал.

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

Разбиение hpp/cpp является подготовительным шагом к следующей работе, где классы выносятся как отдельная библиотека и там тестируются. Т.е. сначала сплошной cpp с классом и main(), далее main() + файлы hpp/cpp, и далее уже main подключает через svn:externals hpp/cpp. Малые шаги лучше чем все сразу.

Фокус на обязательности инкапсуляции и обязательности всех правил оформления кода.

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

Сразу прописывыаем защиту от повторной компиляции — чтобы она стояла везде.

Подробности

Слайды.

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

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

Как это делается в C++. Что это дает (защита, разделение).

Типичная сборка проекта в C++ с точки зрения файлов (пары hpp/cpp, которые независимы и подключаемы при необходимости).

Защита от повторного подключения в С++ (как выглядит и зачем).

Доступ к полям класса (public/private/protected). Что такое наследование пока что не знаем, просто помечаем на будущее. Как это выглядит в C++.

Getter'ы и Setter'ы.

Пример изменения реализации — изменяем private и логику функций, однако интерфейс не изменяется.