Какова точка видимости ООП в PHP, когда доступны Closures and Reflections?
Рассмотрим этот код здесь:
final class TinkerWithMe {
protected $key1 = 19;
private $key2 = 88;
}
$class = new TinkerWithMe();
$getKeys = function() {
return array($this->key1, $this->key2);
};
$oldKeys = $getKeys->call($class);
$newKey1 = 96;
$newKey2 = 42;
$setKeys = function() use ($newKey1, $newKey2) {
$this->key1 = $newKey1;
$this->key2 = $newKey2;
};
$setKeys->call($class);
Зачем беспокоиться о видимости ООП, когда вы можете так легко обойти его с помощью Closures или Reflections?
Есть ли способ блокировать такие вещи, которые мне не хватает?
Ответы
Ответ 1
Модификаторы видимости не являются защитой от одетых в оболочку или обеспечивают какую-либо безопасность или что-то в этом роде. Они являются маркерами того, как предполагается использовать фрагмент кода.
При написании фрагмента кода, подобного классу, вместе с ним собираются другие фрагменты кода; что вы будете писать другой код, который вызывает методы этого класса или обращается к свойствам этого класса. Чтобы свести к минимуму связь с абсолютным значением, вам нужно будет как можно меньше поддерживать открытый интерфейс класса. Когда вы обозначаете что-то как public
, вы отмечаете его "для общего использования". Этот публичный фрагмент должен быть довольно стабильным и не меняться, или вы рискуете сломать много связанного кода, если вы его измените.
Маркировка чего-либо как protected
или private
обозначает эти части как не для общего потребления; он поясняет, что эти детали реализации могут измениться в будущем или не должны использоваться другим кодом "не в курсе". Это позволяет вам легче реорганизовать эти части позже по мере необходимости и лучше понять, какие другие части могут сломаться в результате. Это также помогает обеспечить внутреннее состояние класса, когда внешний код не будет напрямую изменять внутренние значения без полного понимания того, как он должен это делать.
PHP поможет вам почитать эти маркеры в общем случае, бросая ошибки, когда наивно пытается получить доступ к свойствам protected
или private
"извне"; что предотвращает наиболее случайное использование и нежелательную связь. PHP не собирается наклоняться назад, чтобы гарантировать, что эти объекты остаются недоступными при любых возможных обстоятельствах. Если вы действительно стремитесь стрелять своей ногой, пусть будет так. Возможно, вам нужно сделать это для тестирования; это было бы контрпродуктивным, чтобы полностью помешать вам сделать это.
В мантре Python:
Мы все соглашаем взрослых здесь.
Ответ 2
Отличный вопрос! Я хотел бы добавить еще несколько пунктов
Цель указания видимости на языках ООП:
- Чтобы показать, что должны делать свойства и методы. Это должно дать ясность разработчикам относительно того, как получить доступ/изменить свойство и методы, решить, расширять класс или нет.
- Свойства, установленные внутри соответствующего класса, проверяются и устанавливаются для исправления значений, и его безопасно использовать внутри класса без проверки типа свойства.
- Это не надежный способ защитить данные от изменений.
Цель закрытий - бросить кусок функции в переменную или другую функцию для выполнения некоторой активности время от времени. Вместо того, чтобы выделять отдельный код раздела в глобальной области для выполнения действия раз в то время, а не смотреть на него позже, вы можете использовать закрытие.
Размышления предназначены для интроспекции объектов, чтобы знать его свойства, методы, класс и т.д. Полезно идентифицировать зависимости.
Larvel использует отражение для выполнения инъекции зависимостей объектов.
Да, как вы сказали, вы можете использовать Closures and Reflection для работы над видимостью, но его следует рассматривать как функцию языка, а не из-за дефекта дизайна, поскольку ни один язык не может обеспечить данные 100%