русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Динамические посредники


Дата добавления: 2015-06-12; просмотров: 811; Нарушение авторских прав


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

//. typeinfo/SimpleProxyDemo.java

package typeinfo;

import static.net.mindview.util.Print.*;

interface Interface {

void doSomething();

void somethingElse(String arg);

}

 

class RealObject implements Interface {

@Override

public void doSomething() {print("doSomething"); }

@Override

public void somethingElse(String arg) { print("somethingElse " + arg);}

}

 

class SimpleProxy implements Interface {

private Interface proxied;

public SimpleProxy(Interface proxied) { this.proxied = proxied;}

 

@Override

public void doSomething() {

print("SimpleProxy doSomething");

proxied.doSomething();

}

@Override

public void somethingElse(String arg) {

print("SimpleProxy somethingElse " + arg);

proxied.somethingElse(arg);

}

}

class SimpleProxyDemo {

public static void consumer(Interface iface) {

iface.doSomething();

iface.somethingElse("bonobo");

}

public static void main(String[] args) {

consumer(new RealObject());

consumer(new SimpleProxy(new RealObject()));

}

}

<spoiler text="Output:">

doSomething somethingElse bonobo SimpleProxy doSomething doSomething

SimpleProxy somethingElse bonobo

somethingElse bonobo

</spoiler> Поскольку consumer() получает Interface, он не знает, что ему передается — «настоящий» объект (RealObject) или посредник (Proxy), потому что оба типа реализуют Interface. Объект Proxy, находящийся между клиентом и «настоящим» объектом, выполняет операции, а затем вызывает идентичные методы RealObject. Посредник пригодится в любой ситуации, когда требуется отделить дополнительные операции от «настоящего» объекта, и особенно когда нужно легко переключаться из режима использования дополнительных операций в режим отказа от них (и наоборот — главной целью паттернов является инкапсуляция изменений, поэтому для оправдания их применения что-то должно изменяться). Допустим, вы хотите отслеживать вызовы методов RealObject, измерять затраты на эти вызовы, и т. д. Такой код не должен встраиваться в приложение, а посредник позволит легко добавить или убрать его по мере необходимости. Динамические посредники Java развивают концепцию посредника — и объект посредника создается динамически, и обработка вызовов опосредованных методов тоже осуществляется динамически. Все вызовы, обращенные к динамиче­скому посреднику, перенаправляются одному обработчику, который определяет, что это за вызов и как с ним следует поступить. Вот как выглядит примерSimpleProxyDemo.java, переписанный для динамического посредника:



// typeinfo/SimpleDynamicProxy.java

package typeinfo;

import java.lang.reflect.*;

 

class DynamicProxyHandler implements InvocationHandler {

private Object proxied;

public DynamicProxyHandler(Object proxied) {

this.proxied = proxied;

}

 

@Override

public Object invoke(Object proxy, Method method, Object[] args)

throws Throwable {

System.out.println ("**** proxy. " + proxy.getClass()

+ ", method- " + method + ", args " + args);

if(args != null)

for(Object arg : args)

System.out.println(" " + arg);

 

return method.invoke(proxied, args);

}

}

 

class SimpleDynamicProxy {

 

public static void consumer(Interface іface) {

іface.doSomething();

іface.somethingElse("bonobo");

}

public static void main(String[] args) {

RealObject real = new RealObject();

consumer(real);

// Вставляєм посредника и вызываем снова:

Interface proxy = (Interface)Proxy.newProxyInstance(

Interface.class.getClassLoader(),

new Class[]{Interface.class},

new DynamicProxyHandler(real));

consumer(proxy);

}

}

<spoiler text="Output:">

**** proxy: class SProxy(). method: public abstract void Interface.doSomething(), args: null

doSomething

**** proxy: class SProxy(). method: public abstract void

Interface.somethingElse(java.1ang.String),

args: [Ljava.1ang.Object.@42e816

bonobo

somethingElse bonobo

</spoiler> Динамический посредник создается вызовом статического метода Proxy.newProxyInstance(), которому должен передаваться загрузчик класса, список интерфейсов, которые должны реализовываться посредником (а не классов или абстрактных классов!), а также реализация интерфейса InvocationHandler. Динамический посредник перенаправляет все вызовы обработчику, поэтому конструктор обработчика обычно получает ссылку на «настоящий» объект для пере­направления ему запросов. Метод invoke() получает объект посредника на случай, если ему понадобится определить, откуда поступил запрос — впрочем, обычно это несущественно. Будьте внимательны при вызове методов посредника из invoke(), потому что вызовы через интерфейс перенаправляются через посредника. В общем случае вы выполняете опосредованную операцию, а затем используете Method.invoke() для перенаправления запроса опосредованному объекту с передачей необходимых аргументов. При этом некоторые вызовы методов могут отфильтровываться, а другие — проходить:

//: typeinfo/SelectingMethods.java

// Looking for particular methods in a dynamic proxy.

import java.lang.reflect.*;

import static net.mindview.util.Print.*;

 

class MethodSelector implements InvocationHandler {

private Object proxied;

public MethodSelector(Object proxied) {

this.proxied = proxied;

}

public Object

invoke(Object proxy, Method method, Object[] args)

throws Throwable {

if(method.getName().equals("interesting"))

print("Proxy detected the interesting method");

return method.invoke(proxied, args);

}

}

 

interface SomeMethods {

void boring1();

void boring2();

void interesting(String arg);

void boring3();

}

 

class Implementation implements SomeMethods {

public void boring1() { print("boring1"); }

public void boring2() { print("boring2"); }

public void interesting(String arg) {

print("interesting " + arg);

}

public void boring3() { print("boring3"); }

}

 

class SelectingMethods {

public static void main(String[] args) {

SomeMethods proxy= (SomeMethods)Proxy.newProxyInstance(

SomeMethods.class.getClassLoader(),

new Class[]{ SomeMethods.class },

new MethodSelector(new Implementation()));

proxy.boring1();

proxy.boring2();

proxy.interesting("bonobo");

proxy.boring3();

}

}

<spoiler text="Output:">

boring1

boring2

Proxy detected the interesting method

interesting bonobo

boring3

</spoiler> В данном случае мы просто проверяем имена методов, но с таким же успехом можно анализировать другие аспекты сигнатуры и даже значения аргументов. Вряд ли вам придется каждый день пользоваться динамическими посредниками, но они хорошо подходят для решения многих разновидностей задач.



<== предыдущая лекция | следующая лекция ==>
Извлечение информации о методах класса | Объекты с неопределенным состоянием


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 0.072 сек.