В общем, объект Proxy - это объект (экземпляр класса), который предоставляет тот же открытый интерфейс, что и «реальный класс», но просто перенаправляет все вызовы, сделанные его членами, в другой реальный класс. Прокси-объекты используются по разным причинам ...
Одна из целей состоит в том, чтобы «притвориться» реальным классом, чтобы клиентский компонент (или объект) мог «верить», что он говорит с «реальным» объектом, но внутри прокси-сервера, других вещей (таких как ведение журнала, поддержка транзакций). и т. д.) выполняется одновременно ... Во-вторых, прокси может быть очень дешевым по сравнению с реальным объектом. и часто используется для сохранения реальных объектов (выключения или выпуска в пул для использования другими клиентами), когда клиент их не использует ... Прокси-сервер остается "живым", и клиент думает, что он все еще имеет соединение с реальным объектом, но всякий раз, когда он «вызывает» объект, он фактически вызывает прокси-сервер, который отправляет и получает другой реальный объект только для обработки вызова, а затем освобождает реальный объект после завершения вызова.
Что касается Инверсия управления (IOC). Это относится к общему шаблону (также называемому «Внедрение зависимости»), где зависимые объекты внутри класса «внедряются» в экземпляр объекта. class, из клиентского кода, для управления тем, какую версию зависимого объекта будет использовать экземпляр ... IOC можно использовать для внедрения объекта "Proxy" в класс, где он считает, что использует реальный объект ... Фраза Инверсия управления относится к тому факту, что при использовании этого шаблона решение о том, какая фактическая реализация вызывается, больше не контролируется классом, выполняющим вызов, а клиентом этого класса, когда он вставляет экземпляр зависимого объекта в класс, который будет использоваться для этого вызова.
Обычно термин IOC используется с так называемым Контейнером IOC , который является классом, специально предназначенным для того, чтобы отвечать за создание экземпляров зависимых классов на основе слабосвязанной информации об этих классах (типах), которые он получает из какого-то другого источника, кроме аппаратных зависимостей (чаще всего из какого-то файла конфигурации). Как правило, когда вы используете контейнер IOC, вы создаете его экземпляр при запуске приложения, а затем (путем чтения данных конфигурации или чего-либо еще) вы «регистрируете» каждый из классов (типов), за которые будет отвечать контейнер IOC. , со значением ключа. Ключом часто является абстрактный тип или интерфейс, который должны реализовывать все экземпляры этой регистрации). Затем в обычных операциях вашего приложения, где в противном случае вы могли бы создать новый экземпляр экземпляра одного из этих типов, вы вызываете контейнер IOC и вместо этого запрашиваете его экземпляр, используя абстрактный тип / интерфейс в качестве ключа. , Затем контейнер IOC использует отражение или динамическую загрузку (или что-то еще) для создания экземпляра любого типа, который был «зарегистрирован» с этим ключом. Таким образом, просто изменяя данные конфигурации, вы можете контролировать фактические типы, используемые приложением, изменяя их в одной среде или в месте развертывания по сравнению с теми, которые используются в другой.