Должны ли инкапсулированные объекты быть публичными или частными? - PullRequest
5 голосов
/ 09 июня 2011

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

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

Просто примечание: я понимаю, что истинная инкапсуляция подразумевает, что члены являются частными.

Ответы [ 5 ]

2 голосов
/ 09 июня 2011

Чем опасны объекты, выставленные таким образом?

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

Обратите внимание, что именно поэтому свойства полезныв таких языках, как Python, который технически не имеет закрытых членов класса, в большинстве случаев только затемненные.

1 голос
/ 02 июля 2011

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

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

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

  • Позже вы понимаете, что один из ваших экземпляров vars является избыточным и может быть получен на основе других переменных.Еще раз: легко, если вы используете методы доступа, невозможно с общедоступными переменными.

Я думаю, что это сводится к практической точке - если вы знаете, что вы единственный, ктобудет использовать этот код, и вам будет больно писать средства доступа (каждая IDE сделает это за вас автоматически), и вы не возражаете изменить свой собственный код позже, если вы решите нарушить API, а затем пойти на это.Но если другие люди будут использовать ваш класс или если вы захотите упростить рефакторинг позже для собственного использования, оставайтесь с аксессуарами.

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

Ну, вы можете проверить сообщение:

сначала это

затем это

Это должно решить вашу путаницу. Это решило мое!Спасибо Николь Болас .

Также прочитайте комментарии ниже принятого ответа (также обратите внимание на ссылку, данную мной во втором последнем комментарии (в первом посте))

Также посетите пост википедии

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

Вы можете столкнуться с проблемами в зависимости от языка, который вы используете, и от того, как он обрабатывает операторы return или операторы присваивания. В некоторых случаях он может дать вам ссылку или значения в других случаях.

Например, скажем, у вас есть класс PrimeCalculator, который вычисляет простые числа, а затем у вас есть другой класс, который делает что-то с этими простыми числами.

public PrimeCalculator calculatorObject = new PrimeCalculator();

Vector<int> primeNumbers = calculatorObject.PrimeNumbersVector;
/* do something complicated here */
primeNumbers.clear(); // free up some memory

Когда вы используете этот материал позже, возможно, в другом классе, вам не нужны дополнительные вычисления для повторного вычисления чисел, поэтому вы используете тот же calculatorObject.

Vector<int> primes = calculatorObject.PrimeNumbersVector;
int tenthPrime = primes.elementAt(9);

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

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

0 голосов
/ 09 июня 2011

Объектно-ориентированный дизайн - это всего лишь руководство.Подумайте об этом с точки зрения человека, который будет использовать ваш класс.Balance OOD делает его интуитивно понятным и простым в использовании.

...