Неинкапсулированный означает Неизменный? - PullRequest
4 голосов
/ 02 июля 2011

Я сталкивался с этой строкой в ​​ Effective C ++ :

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

Что автор имеет в виду под "Публичным" означает неинкапсулированный и практически говоря неинкапсулированный означает "неизменяемый"?

А как неинкапсулированный неизменен?

Ответы [ 4 ]

7 голосов
/ 02 июля 2011

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

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

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

Это не имеет значенияправил C ++;это просто вопрос правил дизайна интерфейса.Поскольку публичные вещи являются частью интерфейса, вы должны быть осторожны с тем, что вы делаете публичным.

3 голосов
/ 02 июля 2011

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

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

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

Позже вы можете решить, что вам нужна карта для управления всеми этими строками (ваши требования изменились). Вы измените определение элемента данных на карту, и ваш код больше не будет компилироваться. Это значение слова «практически неизменный».

«Правильный» способ управления этим путем инкапсуляции - сделать элемент данных приватным и определить метод интерфейса, например:

std::string getStringWithKey(int index);

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

Это упрощение, потому что дизайн интерфейсов не прост, и интерфейсы тоже меняются, но я надеюсь, что это помогает прояснить ситуацию.

2 голосов
/ 02 июля 2011

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

0 голосов
/ 02 июля 2011

Он имеет в виду членов данных и говорит, что публичное раскрытие элементов данных как части открытого интерфейса означает, что вы никогда не сможете изменить их природу, , т. Е. Имя и тип.

...