Как правильно писать тесты 46 Цикл разработки 46 Структура проекта с тестами 51 Утверждения (Asserts) 52 Утверждения в форме ограничений 54 Категории 56

Вид материалаТесты

Содержание


Основные принципы Абстракция данных
Сокрытие данных
Наследование применяется
Для специфицирования
Для расширения
Для обобщения
Для ограничения
Для выделения различий
Для комбинирования
Подобный материал:
1   2   3   4   5   6   7   8   9   ...   47

Основные принципы

Абстракция данных


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


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

В ООП абстракцию обычно отражает класс.

Инкапсуляция


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

С понятием инкапсуляции связано понятие связности (Cohesion), т.е. узкой специализации класса, высокой специализированности.

Давно известно, что чем меньше в системе одна часть зависит от другой, тем лучше вся система. Такие системы легче ремонтировать и развивать. Говорят, что для таких систем должна быть минимально возможной связанность (Coupling) между элементами и каждый элемент должен быть узкоспециализированным (у него должна быть высокой связность (Cohesion)). Чем больше зависимостей объектов друг от друга (чем больше они знают друг о друге), тем выше связанность. Когда мы собираем систему из объектов, мы связываем составные части друг с другом. Это необходимая связанность системы. В то же время, когда мы разрабатываем конкретный объект, мы даем ему сведения о других объектах, т.е. получаем избыточную связанность. Избыточная связанность затрудняет повторное использование объектов и понижает надежность таких систем.

Связность объекта – это мера зависимостей его частей. Например, если объект «дата» состоит из объектов «месяц», «день», «год» и объекта «цвет», то объект «цвет» понижает связность объекта дата. Объекты с низкой связностью (не узкоспециализированные) с большой вероятностью придется со временем менять. Кроме того, такие объекты сложно использовать повторно.


Сокрытие данных

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


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


Наследование


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


Заменяемость

Если объект класса Х может быть заменен на объект класса Y без каких-либо ограничений, то имеет место заменяемость. Это свойство нужно для того, чтобы можно было сначала писать код, использующий классы (и получить работающую систему), а затем уже сами классы.


Наследование применяется:
  1. Для уточнения. Подкласс – это уточненная версия базового класса. Общее состояние и поведение передвигаем вверх по иерархии. К подклассу применимо выражение «является разновидностью базового класса». Всё что верно для базового класса верно и для подкласса.
  2. Для специфицирования. Иногда нужно наложить ограничения на то, как должен выглядеть подкласс. Для этого подкласс обязывают реализовать некоторый интерфейс. Это позволяет единообразно отправлять одинаковые сообщения всем объектам базового класса. Кроме того, если нужен интерфейс определенного вида, но как сделать реализацию пока не ясно, то обязательства по реализации интерфейса откладываются на время разработки подклассов.
  3. Для расширения. Подклассы добавляют новые возможности к базовому классу. Подклассы являются разновидностями базового класса, поэтому возможности родительского класса остаются им доступными.
  4. Для обобщения. Прямо противоположный уточнению способ. В подклассе обобщается функциональность, присутствующая в базовом классе, путем переопределения методов. Например, базовый класс: монохромный монитор, подкласс: цветной монитор. Если есть доступ к иерархии классов, то желательно так не делать, а изменить требуемым образом базовый класс. Если же нет доступа, то приходится фактически переворачивать направление наследования.
  5. Для ограничения. В подклассах каким-то образом урезается поведение или интерфейс базового класса, например, нужно убрать некоторый метод из унаследованного интерфейса. Например, Профессор → Программист → Работник. Программист является работником и у него есть метод «писать программы целый день», профессор является программистом, но он не пишет программы целый день, поэтому у него метод «писать программы целый день» нужно «выключить».
  6. Для выделения различий. Если вдруг оказывается, что два несвязанных класса имеют похожую функциональность или похожий интерфейс, то можно сделать один базовый класс, чтобы выделить общее и устранить дублирование. Если такая ситуация возникла, то это признак того, что нужно ввести абстрактный базовый класс или интерфейс (если в языке есть поддержка интерфейсов). Интерфейсы могут быть общими для несвязанных классов.
  7. Для комбинирования. Новый класс создается из элементов существующих классов. Для этого используется множественное наследование, существующее в некоторых языках.