Чтение онлайн

на главную - закладки

Жанры

Философия Java3

Эккель Брюс

Шрифт:

//. typeinfo/SimpleProxyDemo java import static net mindview.util Print *,

interface Interface { void doSomethingO; void somethingElse(String arg).

}

class Real Object implements Interface {

public void doSomethingO { printC'doSomething"); } public void somethingElse(String arg) { printC'somethingElse " + arg),

}

}

class SimpleProxy implements Interface { private Interface proxied, public SimpleProxy(Interface proxied) { this.proxied = proxied,

}

public void doSomethingO {

print("SimpleProxy doSomething"), proxied doSomethingO,

}

public void somethingElse(String arg) {

print("SimpleProxy somethingElse " + arg); proxied.somethingElse(arg);

}

class SimpleProxyDemo {

public static void consumer^Interface iface) { iface doSomethingO; iface somethingElseC'bonobo");

}

public static void main(String[] args) { consumer(new RealObjectO), consumer(new SimpleProxy(new RealObjectO)),

}

} /* Output doSomething somethingElse bonobo SimpleProxy doSomething doSomething

SimpleProxy somethingElse bonobo

somethingElse bonobo */// ~

Поскольку consumer

получает Interface, он не знает, что ему передается — «настоящий» объект (RealObject) или посредник (Proxy), потому что оба типа реализуют Interface. Объект Proxy, находящийся между клиентом и «настоящим» объектом, выполняет операции, а затем вызывает идентичные методы RealObject.

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

Динамические посредники Java развивают концепцию посредника — и объект посредника создается динамически, и обработка вызовов опосредованных методов тоже осуществляется динамически. Все вызовы, обращенные к динамическому посреднику, перенаправляются одному обработчику, который определяет, что это за вызов и как с ним следует поступить. Вот как выглядит пример SimpleProxyDemo.java, переписанный для динамического посредника:

// typeinfo/SimpleDynamicProxy java import java lang.reflect *.

class DynamicProxyHandler implements InvocationHandler { private Object proxied; public DynamicProxyHandler(Object proxied) { this proxied = proxied,

}

public Object

invoke(Object proxy, Method method, Object[] args) throws Throwable {

System out.printlnC'**** proxy. " + proxy.getClass +

method- " + method + ", args " + args); if(args != nul 1) продолжение &

for(Object arg : args)

System.out.println(" " + arg); return method.invoke(proxied, args);

}

}

class SimpleDynamicProxy {

public static void consumer(Interface iface) { iface.doSomething; i face.somethi ngElse("bonobo");

}

public static void main(String[] args) {

Real Object real = new Real ObjectО; consumer(real);

//

Вставляем посредника и вызываем снова: Interface proxy = (Interface)Proxy.newProxyInstance( Interface.class.getClassLoader, new Class[]{ Interface.class }. new DynamicProxyHandler(real)); consumer(proxy);

}

} /* Output. doSomething somethingElse bonobo

**** proxy: class SProxyO. method: public abstract void Interface.doSomething, args: null

doSomething

**** proxy: class SProxyO. method: public abstract void

Interface.somethi ngElse(java.1ang.Stri ng), args: [Ljava.1ang.Object.@42e816

bonobo somethingElse bonobo *///:-

Динамический посредник создается вызовом статического метода Proxy. newProxyInstance, которому должен передаваться загрузчик класса, список интерфейсов, которые должны реализовываться посредником (а не классов или абстрактных классов!), а также реализация интерфейса Invocation Handler. Динамический посредник перенаправляет все вызовы обработчику, поэтому конструктор обработчика обычно получает ссылку на «настоящий» объект для перенаправления ему запросов.

Метод 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. Objectd args) throws Throwable {

i f(method.getName.equals("i nteresti ng"))

print("Посредник обнаружил интересный метод"); return method.invoke(proxied. args);

}

}

interface SomeMethods { void boringlO; void boring2; void interesting(String arg). void boring3;

}

class Implementation implements SomeMethods { public void boringlO { printC'boringl"); } 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.

Поделиться:
Популярные книги

Журнал «Если», 2002 № 08

Андерсон Кевин Джей
114. Журнал Если
Фантастика:
научная фантастика
5.00
рейтинг книги
Журнал «Если», 2002 № 08

Стеллар. Заклинатель

Прокофьев Роман Юрьевич
3. Стеллар
Фантастика:
боевая фантастика
8.40
рейтинг книги
Стеллар. Заклинатель

Кодекс Охотника XXVIII

Винокуров Юрий
28. Кодекс Охотника
Фантастика:
фэнтези
боевая фантастика
попаданцы
5.00
рейтинг книги
Кодекс Охотника XXVIII

Товарищ "Чума" 6

lanpirot
6. Товарищ "Чума"
Фантастика:
городское фэнтези
попаданцы
альтернативная история
5.00
рейтинг книги
Товарищ Чума 6

Потомок бога

Решетов Евгений Валерьевич
1. Локки
Фантастика:
попаданцы
альтернативная история
аниме
сказочная фантастика
5.00
рейтинг книги
Потомок бога

Газлайтер. Том 26

Володин Григорий Григорьевич
26. История Телепата
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Газлайтер. Том 26

Кодекс Охотника. Книга XV

Винокуров Юрий
15. Кодекс Охотника
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XV

Эволюционер из трущоб. Том 4

Панарин Антон
4. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Эволюционер из трущоб. Том 4

Рассвет русского царства

Грехов Тимофей
1. Новая Русь
Документальная литература:
историческая литература
5.00
рейтинг книги
Рассвет русского царства

Война

Валериев Игорь
7. Ермак
Фантастика:
боевая фантастика
альтернативная история
5.25
рейтинг книги
Война

Тринадцатый

Северский Андрей
Фантастика:
фэнтези
рпг
7.12
рейтинг книги
Тринадцатый

Бастард рода Неллеров. Книга 1

Усов Серг
1. Бастард рода Неллеров
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Бастард рода Неллеров. Книга 1

Газлайтер. Том 25

Володин Григорий Григорьевич
25. История Телепата
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Газлайтер. Том 25

Сирийский рубеж 2

Дорин Михаил
6. Рубеж
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Сирийский рубеж 2