Размер шрифта
-
+

Чистая архитектура. Искусство разработки программного обеспечения - стр. 17

Именно эти ограничения мы будем подробно изучать в последующих главах.

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



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

Один из возможных ответов на этот вопрос: «комбинация данных и функций». Однако, несмотря на частое цитирование, этот ответ нельзя признать точным, потому что он предполагает, что >o.f() – это нечто отличное от >f(o). Это абсурд. Программисты передавали структуры в функции задолго до 1966 года, когда Даль и Нюгор перенесли кадр стека функции в динамическую память и изобрели ОО.

Другой распространенный ответ: «способ моделирования реального мира». Это слишком уклончивый ответ. Что в действительности означает «моделирование реального мира» и почему нам может понадобиться такое моделирование? Возможно, эта фраза подразумевает, что ОО делает программное обеспечение проще для понимания, потому что оно становится ближе к реальному миру, но и такое объяснение слишком размыто и уклончиво. Оно не отвечает на вопрос, что же такое ОО.

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

Давайте исследуем эти понятия по очереди.

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

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

Эта идея определенно не уникальная для ОО. Например, в языке C имеется превосходная поддержка инкапсуляции. Рассмотрим простую программу на C:


>point.h

>struct Point;

>struct Point* makePoint(double x, double y);

>double distance (struct Point *p1, struct Point *p2);


>point.c

>#include "point.h"

>#include

>#include

>struct Point {

> double x,y;

>};


>struct Point* makepoint(double x, double y) {

> struct Point* p = malloc(sizeof(struct Point));

> p->x = x;

> p->y = y;

> return p;

>}


>double distance(struct Point* p1, struct Point* p2) {

> double dx = p1->x – p2->x;

> double dy = p1->y – p2->y;

> return sqrt(dx*dx+dy*dy);

>}


Пользователи >point.h не имеют доступа к членам структуры >Point. Они могут вызывать функции >makePoint() и >distance(), но не имеют никакого представления о реализации структуры Point и функций для работы с ней.

Это отличный пример поддержки инкапсуляции не в объектно-ориентированном языке. Программисты на C постоянно использовали подобные приемы. Мы можем объявить структуры данных и функции в заголовочных файлах и реализовать их в файлах реализации. И наши пользователи никогда не получат доступа к элементам в этих файлах реализации.

Но затем пришел объектно-ориентированный C++ и превосходная инкапсуляция в C оказалась разрушенной.

По техническим причинам[12] компилятор C++ требует определять переменные-члены класса в заголовочном файле. В результате объектно-ориентированная версия предыдущей программы Point приобретает такой вид:

Страница 17