Отражение повреждает принцип инкапсуляции?

Различие в производительности было не важно с тех пор, по крайней мере, январь 2012, и вероятно ранее:

Single quotes: 0.061846971511841 seconds
Double quotes: 0.061599016189575 seconds

Более ранние версии PHP, возможно, имели различие - я лично предпочитаю одинарные кавычки двойным кавычкам, таким образом, это было удобное различие. Заключение статьи высказывает точное мнение:

Никогда не доверяют статистической величине Вы, didn’t создают себя.

(Хотя статья заключает фразу в кавычки, исходное тонкое замечание было вероятно ложно , приписал Winston Churchill, изобретенному министерством пропаганды Joseph Goebbels' для описания Churchill как лгуна:

Ich traue keiner Statistik, умрите ich nicht selbst gefГ¤lscht habe.

Это свободно переводит в, "Я не доверяю статистической величине, которую я не фальсифицировал сам".)

10
задан Sorin Comanescu 25 November 2009 в 10:47
поделиться

9 ответов

Reflection breaks encapsulation principles by giving access to private fields and methods, but it's not the first or only way in which encapsulation can be circumvented; one could argue that serialization exposes all the internal data of a class, information which would normally be private.

It's important to understand that encapsulation is only a technique, one that makes designing behaviour easier, provided consumers agree use an API you have defined. If somebody chooses to circumvent your API using reflection or any other technique, they no longer have the assurance that your object will behave as you designed it. If somebody assigns a value of null to a private field, they'd better be ready to catch a NullReferenceException the next time they try to use your class!

In my experience, programming is all about assertions and assumptions. The language asserts constraints (classes, interfaces, enumerations) which make creating isolated behaviour much easier to produce, on the assumption that a consumer agrees to not violate those boundaries.

This is a fair assertion to make given it makes a divide-and-conquer approach to software development more easy than any technique before it.

15
ответ дан 3 December 2019 в 13:51
поделиться

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

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

С другой стороны, есть некоторые задачи, которые нельзя было бы решить без этого механизма, например, работа с генерируемыми типами времени выполнения (хотя, начиная с .NET 4.0 с его DLR, это будет намного проще). и «динамические» переменные в C # 4.0).

9
ответ дан 3 December 2019 в 13:51
поделиться

Я полагаю, вы могли бы так сказать. Можно также сказать, что API-интерфейсы CodeDom, Reflection Emit и Expression Tree нарушают инкапсуляцию, позволяя писать код «на лету». Это просто средства, предоставляемые .NET. Вам не обязательно их использовать.

Не забывайте, что вы должны (а) работать с полным доверием и (б) явно указать BindingFlags.NonPublic , чтобы получить доступ к частным данные. Этого должно быть достаточно для подстраховки.

3
ответ дан 3 December 2019 в 13:51
поделиться

Это часть функциональности, предоставляемой Reflection, но, я бы сказал, не лучшее ее использование.

Она работает только при полном доверии.

2
ответ дан 3 December 2019 в 13:51
поделиться

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

1
ответ дан 3 December 2019 в 13:51
поделиться

Можно сказать, что отражение ломает также наследование и полиморфизм. Когда вместо того, чтобы предоставлять каждому типу объекта его собственную версию перегруженного метода, у вас есть единственный метод, который проверяет тип объекта во время выполнения и переключается на определенное поведение для каждого.

Тем не менее, отражение - хороший инструмент. Иногда вам нужно создать экземпляр объекта с частным конструктором, потому что это оптимальный курс действий, и вы не можете изменить реализацию класса (закрытая библиотека, больше нельзя связаться с автором). Или вы хотите выполнить некоторую вспомогательную операцию над множеством объектов в одном месте. Или, может быть, вы хотите выполнить регистрацию для определенных типов. Это ситуации, когда размышление действительно помогает, не причиняя никакого вреда.

2
ответ дан 3 December 2019 в 13:51
поделиться

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

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

Если вы думаете, что отражение должно быть невозможным , вы мечтаете!

В В C ++ нет отражения как такового. Но существует базовая «объектная модель», которую машинный код, созданный компилятором, использует для доступа к структуре объектов (и виртуальным функциям). Таким образом, программист на C ++ может таким же образом нарушить инкапсуляцию.

class RealClass
{
private:
    int m_secret;
};

class FakeClass
{
public:
    int m_notSecret;
};

Мы можем взять указатель на объект типа RealClass и просто преобразовать его в FakeClass и получить доступ к «частному» члену.

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

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

(function() {

    var x = 5;

    myGetter = function() { return x; };
    mySetter = function(v) { x = v; };

})();

После этого глобальное пространство имен будет содержать две функции, myGetter и mySetter , которые являются единственным способом получить доступ к значению x . Javascript не имеет отражающей способности для получения x любым другим способом. Но он должен запускаться в каком-то интерпретаторе хоста (например, в браузере), и поэтому определенно существует ужасный способ манипулировать x . Ошибка повреждения памяти в плагине могла произойти случайно!

4
ответ дан 3 December 2019 в 13:51
поделиться

Принцип инкапсуляции поддерживается вашим API, но отражение дает вам способ обойти API.

Тот, кто использует отражение, знает, что он использует ваш API неправильно!

2
ответ дан 3 December 2019 в 13:51
поделиться

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

Отражение - это инструмент, его можно использовать или злоупотреблять.


Что касается вопроса после вашего редактирования: ответ - просто нет. Разработчик API мог бы сделать все, что в его силах, приложив много усилий, чтобы открыть чистый интерфейс, и увидеть, что его API чрезмерно злоупотребляют, используя отражение.

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

2
ответ дан 3 December 2019 в 13:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: