Читаем Как функции, не являющиеся методами, улучшают инкапсуляцию полностью

Возможно что Вы, как и многие люди, с которыми я обсуждал эту проблему, имеете представление относительно синтаксического смысла моего утверждения, что не методы и не друзья предпочтительнее методов. Возможно, что Вы даже "купились" на мои аргументы относительно инкапсуляции. Теперь, предположим, что класс Wombat (Вомбаты – семейство австралийских млекопитающих отряда сумчатых. Благодарю Алекса за коррекцию перевода. А.Л.) поддерживает функциональные возможности, поедания и засыпания. Далее предположим, что функциональные возможности, связанные с поеданием, должны быть выполнены как метод, а засыпание может быть выполнено как член или как не член и не друг. Если Вы следуете моим советам, описанным выше, вы создадите описание подобные этим:

class Wombat {

public:

 void eat(double tonsToEat);

 …

};

void sleep(Wombat& w, double hoursToSnooze);

Это привело бы к синтаксическому противоречию для клиентов класса, потому что для

Wombat w;

они напишут:

w.eat(.564);

при вызове eat. Но они написали бы:

sleep(w, 2.57);

для выполнения sleep. При использовании только методов класса можно было бы иметь более опрятный код:

class Wombat {

public:

 void eat(double tonsToEat);

 void sleep(double hoursToSnooze);

 …

};


w.eat(.564);

w.sleep(2.57);

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

Чтобы непосредственно ее использовать, нужны функции – не методы. Позвольте нам продолжить пример Wombat. Предположим, что Вы пишете программу моделирования этих прожорливых созданий, и воображаете, что одним из методов, в котором Вы часто нуждаетесь при использовании вомбатов, является засыпание на полчаса. Ясно, что Вы можете засорить ваш код обращениями w.sleep (.5), но этих (.5) будет так много, что их будет трудно напечатать. А что произойдет, если это волшебное значение должно будет измениться? Имеется ряд способов решить эту проблему, но возможно самый простой заключается в определении функции, которая инкапсулирует детали того, что Вы хотите сделать. Понятно, что если Вы не являетесь автором Wombat, функция будет обязательно внешней, и вы будете вызвать ее таким образом:

// может быть inline, но это не меняет сути

void nap(Wombat& w) {w.sleep(.5);}


Wombat w;

nap(w);

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

Если Вы самокритичны и честны сами с собой, вы увидите, что имеете эту предполагаемую несогласованность со всеми нетривиальными классами, Вы используете ее потому, что класс не может имеет любую функцию, которую пожелает како-то клиент. Каждый клиент добавляет, по крайней мере, несколько своих функций для собственного удобства, и эти функции всегда не являются методами классов. Программисты на C++ используют это, и они не думают ничего о этом. Некоторые вызовы используют синтаксис методов, а некоторые синтаксис внешних вызовов. Клиенты только ищут, какой из синтаксисов является соответствующим для тех функций, которые они хотят вызвать, затем они вызывают их. Жизнь продолжается. Это происходит особенно часто в STL (Стандартной библиотеки C++), где некоторые алгоритмы являются методами (например, size), некоторые – не методами (например, unique), а некоторые – тем и другим (например, find). Никто и глазом не моргает. Даже Вы.

Интерфейсы и упаковка

Herb Sutterr объяснил, что "интерфейс" класса (подразумевая, функциональные возможности, обеспечиваемые классом) включает также внешние функции, связанные с классом. Им также показано, что правила области видимости имен в C++ поддерживают эти изменения понятия "интерфейса" [7,8]. Это замечательные новости для моего тезиса "не друзья и не члены лучше, чем члены", потому что это означает, что решение сделать функцию, зависимую от класса, в виде не друга – не члена вместо члена даже не изменяет интерфейс этого класса! Кроме того, вывод функций интерфейса класса за границы определения класса ведет к некоторой замечательной гибкости упаковки, которая была бы иначе недоступна. В частности, это означает, что интерфейс класса может быть разбит на множество заголовочных файлов.

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

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

1001 совет по обустройству компьютера
1001 совет по обустройству компьютера

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

Юрий Всеволодович Ревич

Программирование, программы, базы данных / Интернет / Компьютерное «железо» / ОС и Сети / Программное обеспечение / Книги по IT
iOS. Приемы программирования
iOS. Приемы программирования

Книга, которую вы держите в руках, представляет собой новый, полностью переписанный сборник приемов программирования по работе с iOS. Он поможет вам справиться с наболевшими проблемами, с которыми приходится сталкиваться при разработке приложений для iPhone, iPad и iPod Touch. Вы быстро освоите всю информацию, необходимую для начала работы с iOS 7 SDK, в частности познакомитесь с решениями для добавления в ваши приложения реалистичной физики или движений — в этом вам помогут API UIKit Dynamics.Вы изучите новые многочисленные способы хранения и защиты данных, отправки и получения уведомлений, улучшения и анимации графики, управления файлами и каталогами, а также рассмотрите многие другие темы. При описании каждого приема программирования приводятся образцы кода, которые вы можете смело использовать.

Вандад Нахавандипур

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