Почему не рекомендуется постоянно использовать модификатор доступа <br/> public в Unity? Я никогда не задумывался об этом и хотел бы понять причины.
Использование модификаторов доступа в программировании, включая разработку игр в Unity, очень важно для обеспечения гибкости, удобства сопровождения и защиты данных. Вот несколько причин, почему стоит предпочесть `private` и избегать использования `public` везде: ### 1. **Сокрытие реализации (Encapsulation)**: Сокрытие данных и методов от внешнего доступа позволяет вам изменять реализацию класса, не нарушая работу других частей программы. Если вы используете `public`, другие объекты смогут взаимодействовать с вашими переменными напрямую, и любые изменения в коде могут привести к багам или непредвиденному поведению. ### 2. **Упрощение тестирования и отладки**: Если класс содержит публичные поля, тестирование и отладка могут стать более сложными, так как любое изменение внешнего состояния может влиять на продолжение работы программы. С `private` полями вы можете контролировать, как и когда они изменяются, что облегчает нахождение и исправление ошибок. ### 3. **Читаемость и поддержка кода**: Когда поля и методы светятся `public` без необходимости, это может привести к запутанности в коде. Когда вы видите использование `private`, это говорит о том, что программист задумался о внутренней архитектуре класса, что облегчает чтение и понимание кода. ### 4. **Управление состоянием объекта**: Используя `private` для переменных, вы можете предоставлять публичные методы для работы с этими переменными. Это дает вам возможность добавлять валидацию или бизнес-логику, которая не позволила бы "неправильные" значения быть выставленными без контроля. ### 5. **Избежание зависимости**: Если другой класс напрямую обращается к `public` переменной, он создаёт зависимость от внутренней структуры вашего класса. Если вы решите изменить эту структуру, вам нужно будет также изменить код всех классов, которые от неё зависят. ### 6. **Использование свойства (Properties)**: C# поддерживает свойства, которые позволяют вам почти так же удобно использовать свои поля, как и публичные переменные, но с дополнительным контролем доступа и возможностью добавления логики при установке и получении значений. ### 7. **Взаимодействие с Unity и инспектором**: В Unity вы можете использовать атрибут `[SerializeField]` для приватных полей, чтобы они были видимыми в инспекторе. Это позволяет вам сохранять преимущества инкапсуляции, оставаясь при этом удобным для настройки в редакторе. Итак, хотя прямое использование `public` может упростить доступ, лучший подход — это всегда внимательно обдумать, какой именно уровень доступа лучше всего подходит для ваших данных и методов. Использование `private` в большинстве случаев направлено на улучшение качества, гибкости и надежности вашего кода.
Почему рекоменудется носить трусы? Чтобы жопа была в безопасности. <br/> <br/> Вот тут прибилзительно то же самое. Чтобы программисту не надо было думать как поведет себя код, если ВДРУГ кто то снаружи изменит то, что менять не надо вообще. <br/> Когда вы делаете переменную публичной - вы тем самым говорите "эту переменную можно менять, я все предусмотрел, все будет ок. Это интерфейс взаимодействия - пользуйтесь". Но ведь далеко не для всех переменных класса НАДО предусматривать такое - зачем же делать лишнюю работу - ставим private и все, манипулируем переменной только изнутри, ЗНАЯ все варианты ее изменения.
Если без шибко умных слов, то приватными поля нужно делать, чтобы код отображал намерения разработчика и чтобы скрывать детали реализации (польза второго менее очевидна). <br/> <br/> Вот пример из комментариев о том, как делать не стоит: <br/> <pre><code class="cs">class Character {
public double health;
public void TakeDamage(double damage) {
if(damage <= 0) return;
this.health -= damage;
if(this.health <= 0) {
this.Die();
}
// ...
}
public void Die() {
this.DoSomethingSpecial();
// ...
}
// Этот метод в будущем будет удалён, оставлен пока как костыль
public void DoSomethingSpecial() {/*...*/}
}</code></pre> <br/> <br/> Потом спустя хз сколько времени ты вернулся к коду. <br/> Как ты будешь вспоминать, как правильно стоит наносить урон персонажам? <br/> Через TakeDamage или в каких-то случаях можно напрямую изменить поле health? <br/> Если в каких-то случаях нужно напрямую использовать поле health, то в каких? <br/> <br/> Про скрытие деталей реализации: <br/> Допустим, что ты решил добавить в игру поддержку модов. <br/> Как разработчик мода поймёт, какие методы на персонажах можно вызывать не беспокоясь о том, что мод сломается в следующей версии игры? <br/> Например без использования модификатора internal - разработчик мода может подумать, что этот метод можно вызывать, а по факту - в следующей версии ты, как разработчик игры, планируешь его удалить или изменить сигнатуру, что поломает мод. <br/> + если у тебя многие вещи сделаны через поля, то тогда ты не сможешь использовать интерфейсы (ну или их использование будет затруднено)
Одно слово - инкапсуляция. <br/> Если ты делаешь внутренний метод или переменную публично доступной, и работаешь с ней снаружи класса, то когда тебе понадобится изменить эту переменную или метод по работе с ней, тебе понадобится искать все использования этой переменной, а вот если ты заранее ограничишь себя, и для выхода наружу будешь специально создавать методы класса, то в тот момент, когда ты пожелаешь что либо изменить, тебе будет достаточно сделать это внутри класса.. да и искать влияние таких исправлений снаружи по ошибкам компилятора будет проще. <br/> <br/> Ты не только должен делать переменные приватными, тебе необходимо оформить у класса методы по работе с ними таким образом, по возможности, чтобы при использовании класса тебе было бы все равно, как именно у тебя хранятся эти данные... т.е. часто не достаточно просто заворачивать эти переменные в геттеры и сеттеры. <br/> <br/> Тупой пример с координатами персонажа... делаешь эти переменные приватными, и оформляешь методы 'бег вперед', 'поворот' и т.п. а значит снаружи у тебя не будет чего то типа object.pos_x+=object.speed_x а будет object.moveRight().