@DVP88

Чем чревато использование модификатора public?

Приветствую, подскажите, пожалуйста, никак не могу разобраться с использованием модификаторов доступа public, protected и private, назначение их мне понятно, в каком случае и что использовать тоже, но в чем же всё-таки на реальном примере чревато использование public? Максимальное объяснение очень сжато и не ясно, в чём кроется реальная практическая проблема, кроме абстрактного представления ошибки:
Стороннее объяснение

Это плохо по нескольким причинам:
  • Если поле можно изменить в любом месте программы, сложно отслеживать ошибки, потому что не всегда понятно, где что-то пошло не так.
  • Если вдруг в программу во время работы попадёт чужой код, он сможет изменять и читать любые поля любых объектов.

Источник: статья "ООП. Часть 3. Модификаторы доступа, инкапсуляция", не знаю, можно ли озвучивать с какого сайта

В PHP 7.4 появился type hint, и пару англоязычных ресурсов заявляют, что магические методы __get и __set более не требуются, ведь теперь мы можем не боятся, что будут введены не корректные данные. Так ли это? Как действительно стоит использовать модификаторы доступа и воздействовать на переменные с учётом тайп хинта?
  • Вопрос задан
  • 334 просмотра
Решения вопроса 1
php666
@php666
PHP-макака
чем же всё-таки на реальном примере чревато использование public
Ну смотри.
Представь себе, что ты - объект, а все твои свойства (сердце, печень, желудок) - публичные. Я могу к тебе подойти, тыкнуть пальцем в сердце и ты помрешь. Так же и в объектах - те свойства, которые ответственны за работоспособность объекта класса, которые не должны быть доступны извне, делают private/protected.

Как в закрытое свойств (желудок) поместить еду? Сделаем публичный метод ЕСТЬ(), который поместит туда еду. На вход подаем пищу.
Зачем нужен метод, если, теоретически, желудок можно было бы сделать public и класть в него пищу напрямую, с помощью лопаты? Очевидно, метод ЕСТЬ() имеет кое-какую проверку входящих данных. Например, если ты засунешь себе в рот тухлятину, то эта "еда" просто не пойдет дальше - сработает рвотный рефлекс.
Такая же аналогия с программированием - хорошая практика - делать т.н. сеттеры/геттеры методы, которые принимают и возвращают свойства объектов. На эти методы можно повесть некую логику. Например, при установки свойства проверять его корректность, а при возвращении - отдавать в определенном формате.

Когда нужны public-свойства? В очень редких случаях, например когда объект выполняет роль некого хранилища, например это \stdClass -объект верхнего уровня PHP. Но в реальной разработке это очень редкие явления.
Все классы должны иметь закрытые свойства, а для манипуляции с ними - геттеры/сеттеры. Это хорошая практика.

Ну и пример банальный:

// класс для работы с mysql
class Database
{
    /**
     * Ресурс соединения с mysql 
     * @var mysqli
     */
    public $connection;

    public function __construct()
    {
        $this->connection = mysqli_connect(/**/);
    }
}

$db = new Database();

// какой-то петя в коде написал случайно:
$db->connection = 123; // все сломалось
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@bkosun
Простой пример:

class Foo
{
	public $quux;
}

class Bar
{
	private $quux;

	public function setQuux(Quux $quux)
	{
		$this->quux = $quux;
	}
}

class Quux
{
}

$foo = new Foo();
$foo->quux = 'text';  // Work

$foo = new Bar();
$foo->quux = 'text'; // Member has private access


Свойство quux является public свойством класса Foo. При таком подходе можно манипулировать ним как угодно и хранить там любые данные.

С появлением типизированных свойств (PHP 7.4) - можно не использовать сеттеры:

class Foo
{
	public Quux $quux;
}


А что, если в классе есть свойство, которое не должно быть изменено? Идея в том, что класс должен предоставлять API для работы с ним, чтобы исключить возможность сломать логику его работы.

Closing the API allows design flaws to be found more easily and gives you the opportunity to evolve your code by creating well defined extension points.


fabien.potencier.org/pragmatism-over-theory-protec...
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы