Читаем Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ полностью

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

Что следует помнить

• Объявляйте данные-члены закрытыми (private). Это дает клиентам синтаксически однородный доступ к данным, обеспечивает возможность тонкого управления доступом, позволяет гарантировать инвариантность и предоставляет авторам реализации классов гибкость.

• Защищенные члены не более инкапсулированы, чем открытые.

<p>Правило 23: Предпочитайте функциям-членам функции, не являющиеся ни членами, ни друзьями класса</p>

Возьмем класс для представления Web-браузера. В числе прочих такой класс может предлагать функции, который очищают кэш загруженных элементов, очищают историю посещенных URL и удаляют из системы все «куки» (cookies):

class WebBrowser {

public:

...

void clearCache();

void clearHistory();

void removeCookies();

...

};

Найдутся пользователи, которые захотят выполнить все эти действия вместе, поэтому WebBrowser может также предоставить функцию и для этой цели:

class WebBrowser {

public:

...

void clearEveryThing(); // вызывает clearCache(), clearHistory()

// и removeCookies()

...

};

Конечно, такая функциональность может быть обеспечена также функцией, не являющейся членом класса, которая вызовет соответствующие функции-члены:

void clearBrowser(WebBrowser& wb)

{

wb.clearCache();

wb.clearHistory();

wb.removeCache();

}

Что лучше – функция-член clearEverything или свободная функция clear-Browser?

Принципы объектно-ориентированного проектирования диктуют, что данные и функции, которые оперируют ими, должны быть связаны вместе, и это предполагает, что функция-член – лучший выбор. К сожалению, это предположение неверно. Оно основано на непонимании того, что такое «объектно-ориентированный». Да, в объектно-ориентированных программах данные должны быть инкапсулированы, насколько возможно. В противоположность интуитивному восприятию функция-член clearEverything в действительности менее инкапсулирована, чем свободная функция clearBrowser. Более того, предоставление свободной функции позволяет обеспечить большую гибкость при «упаковке» функциональности класса WebBrowser, а это приводит к меньшему числу зависимостей на этапе компиляции и расширяет возможности для расширения класса. Поэтому свободная функция лучше по многим причинам. Важно их отчетливо понимать.

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

Рассмотрим данные, ассоциированные с объектом. Чем меньше существует кода, который видит эти данные (то есть имеет к ним доступ), тем в большей степени они инкапсулированы и тем свободнее мы можем менять их характеристики, например количество членов-данных, их типы и т. п. Грубой оценкой объем кода, который может видеть некоторый член данных, можно считать число функций, имеющих к нему доступ: чем больше таких функций, тем менее инкапсулированы данные.

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

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

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

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

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

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

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

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

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