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

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

point.h

class Point {

public:

  Point(double x, double y);

  double distance(const Point& p) const;

private:

  double x;

  double y;

};

point.cc

#include "point.h"

#include

Point::Point(double x, double y)

: x(x), y(y)

{}

double Point::distance(const Point& p) const {

  double dx = x-p.x;

  double dy = y-p.y;

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

}

Теперь пользователи заголовочного файла point.h знают о переменных-членах x и y! Компилятор не позволит обратиться к ним непосредственно, но клиент все равно знает об их существовании. Например, если имена этих членов изменятся, файл point.cc придется скомпилировать заново! Инкапсуляция оказалась разрушенной.

Введением в язык ключевых слов public, private и protected инкапсуляция была частично восстановлена. Однако это был лишь грубый прием (хак), обусловленный технической необходимостью компилятора видеть все переменные-члены в заголовочном файле.

Языки Java и C# полностью отменили деление на заголовок/реализацию, ослабив инкапсуляцию еще больше. В этих языках невозможно разделить объявление и определение класса.

По описанным причинам трудно согласиться, что ОО зависит от строгой инкапсуляции. В действительности многие языки ОО практически не имеют принудительной инкапсуляции[13].

ОО безусловно полагается на поведение программистов — что они не станут использовать обходные приемы для работы с инкапсулированными данными. То есть языки, заявляющие о поддержке OO, фактически ослабили превосходную инкапсуляцию, некогда существовавшую в C.

<p>Наследование?</p>

Языки ОО не улучшили инкапсуляцию, зато они дали нам наследование.

Точнее — ее разновидность. По сути, наследование — это всего лишь повторное объявление группы переменных и функций в ограниченной области видимости. Нечто похожее программисты на C проделывали вручную задолго до появления языков ОО[14].

Взгляните на дополнение к нашей исходной программе point.h на языке C:

namedPoint.h

struct NamedPoint;

struct NamedPoint* makeNamedPoint(double x, double y, char* name);

void setName(struct NamedPoint* np, char* name);

char* getName(struct NamedPoint* np);

namedPoint.c

#include "namedPoint.h"

#include

struct NamedPoint {

  double x,y;

  char* name;

};

struct NamedPoint* makeNamedPoint(double x, double y, char* name) {

  struct NamedPoint* p = malloc(sizeof(struct NamedPoint));

  p->x = x;

  p->y = y;

  p->name = name;

  return p;

}

void setName(struct NamedPoint* np, char* name) {

  np->name = name;

}

char* getName(struct NamedPoint* np) {

  return np->name;

}

main.c

#include "point.h"

#include "namedPoint.h"

#include

int main(int ac, char** av) {

  struct NamedPoint* origin = makeNamedPoint(0.0, 0.0, "origin");

  struct NamedPoint* upperRight = makeNamedPoint

    (1.0, 1.0, "upperRight");

  printf("distance=%f\n",

    distance(

      (struct Point*) origin,

      (struct Point*) upperRight));

}

Внимательно рассмотрев основной код в файле main.c, можно заметить, что структура данных NamedPoint используется, как если бы она была производной от структуры Point. Такое оказалось возможным потому, что первые два поля в NamedPoint совпадают с полями в Point. Проще говоря, NamedPoint может маскироваться под Point, потому что NamedPoint фактически является надмножеством Point и имеет члены, соответствующие структуре Point, следующие в том же порядке.

Этот прием широко применялся[15] программистами до появления ОО. Фактически именно так C++ реализует единственное наследование.

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

Перейти на страницу:

Все книги серии Библиотека программиста

Программист-фанатик
Программист-фанатик

В этой книге вы не найдете описания конкретных технологий, алгоритмов и языков программирования — ценность ее не в этом. Она представляет собой сборник практических советов и рекомендаций, касающихся ситуаций, с которыми порой сталкивается любой разработчик: отсутствие мотивации, выбор приоритетов, психология программирования, отношения с руководством и коллегами и многие другие. Подобные знания обычно приходят лишь в результате многолетнего опыта реальной работы. По большому счету перед вами — ярко и увлекательно написанное руководство, которое поможет быстро сделать карьеру в индустрии разработки ПО любому, кто поставил себе такую цель. Конечно, опытные программисты могут найти некоторые идеи автора достаточно очевидными, но и для таких найдутся темы, которые позволят пересмотреть устоявшиеся взгляды и выйти на новый уровень мастерства. Для тех же, кто только в самом начале своего пути как разработчика, чтение данной книги, несомненно, откроет широчайшие перспективы. Издательство выражает благодарность Шувалову А. В. и Курышеву А. И. за помощь в работе над книгой.

Чед Фаулер

Программирование, программы, базы данных / Программирование / Книги по IT

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных