Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / смысл в Dynamic Proxy Classes / 23 сообщений из 23, страница 1 из 1
20.01.2012, 16:25:38
    #37624392
OOsalivan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
смысл в Dynamic Proxy Classes
Dynamic Proxy позволяют заменяет вызов всех методов реализуемых интерфейсов некого класса на вызов метода InvocationHandler#invoke. А в чем смысл, если мы можем использовать для этих целей наследование и полиморфизм?
...
Рейтинг: 0 / 0
20.01.2012, 16:34:29
    #37624415
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
смысл в Dynamic Proxy Classes
Смысл в том чтобы для всех методов одного интерфейса выполнить одно и то же действие.
Для того чтобы реализовать это через полиморфизм, необходимо создать класс для каждого метода.
...
Рейтинг: 0 / 0
20.01.2012, 16:35:09
    #37624418
svenom
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
смысл в Dynamic Proxy Classes
Про AOP что-нибудь слышали? Вот это классический AOP как раз. Он сделан как раз специально, что бы не приходилось делать никакого наследования (ну а полиморфизм тут вообще не подходит) для внедрения вспомогательных операций (секьюрити, логирование, LazyLoading и т.д.).
...
Рейтинг: 0 / 0
20.01.2012, 16:38:12
    #37624424
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
смысл в Dynamic Proxy Classes
Писали же не так давно:) Если кратко то основные причины
1) А что если классы не известны на момент загрузки? отчего наследоваться?
2) AOP, Разместить логику, непосредственно не относящуюся к обязанности класса и пересекающуюся для многих классов, в одном централизованном месте гораздо лучше.
3) А что если операция создания проксированного объекта довольно тяжеловесна, а в некоторых случаях хватит прокси? Пример - Hibernate findById()

Есть конечно и минусы
1) Трудность дебага
2) Overengineering

Динамик прокси не стоит пихать везде, где только можно, на это должна быть причина.
...
Рейтинг: 0 / 0
20.01.2012, 16:41:26
    #37624435
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
смысл в Dynamic Proxy Classes
забыл никДинамик прокси не стоит пихать везде, где только можно, на это должна быть причина.
+1
извечная проблема баланса динамика --- статика
...
Рейтинг: 0 / 0
20.01.2012, 17:10:53
    #37624501
OOsalivan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
смысл в Dynamic Proxy Classes
BlazkowiczСмысл в том чтобы для всех методов одного интерфейса выполнить одно и то же действие.
Для того чтобы реализовать это через полиморфизм, необходимо создать класс для каждого метода.

Зачем? Если у нас есть интерфейс с несколькими методами, то мы создаем только один класс с реализацией этих методов... Не понял зачем создавать несколько классов?
...
Рейтинг: 0 / 0
20.01.2012, 17:21:48
    #37624524
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
смысл в Dynamic Proxy Classes
OOsalivanЗачем? Если у нас есть интерфейс с несколькими методами, то мы создаем только один класс с реализацией этих методов... Не понял зачем создавать несколько классов?
Как вы будете выполнять один и тот же код в каждом методе? Копировать вызов утилитного метода в каждый метод реализации?
Proxy нужны не для того чтобы "реализовывать интерфейсы". Обычно, они проксируют конкретную реализацию интерфейса.
Пример. У вас есть интерфейс и две реализации. Результат работы каждого метода вам нужно поместить в кэш. Напишите как это будет выглядеть через ООП и полиморфизм.
...
Рейтинг: 0 / 0
20.01.2012, 17:33:42
    #37624544
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
смысл в Dynamic Proxy Classes
Возможно у вас ещё возникло недопонимание из-за использования интерфейса. Это только ограничение Java Reflection. В реальной жизни Dynamic Proxy можно реализовать и на классе, без каких-либо интерфейсов.
...
Рейтинг: 0 / 0
20.01.2012, 18:24:44
    #37624628
OOsalivan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
смысл в Dynamic Proxy Classes
BlazkowiczOOsalivanЗачем? Если у нас есть интерфейс с несколькими методами, то мы создаем только один класс с реализацией этих методов... Не понял зачем создавать несколько классов?
Как вы будете выполнять один и тот же код в каждом методе? Копировать вызов утилитного метода в каждый метод реализации?
Proxy нужны не для того чтобы "реализовывать интерфейсы". Обычно, они проксируют конкретную реализацию интерфейса.
Пример. У вас есть интерфейс и две реализации. Результат работы каждого метода вам нужно поместить в кэш. Напишите как это будет выглядеть через ООП и полиморфизм.

Опять не совсем понятны условия задачи? Где тут проблема?

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
interface Animal {
	String getName();
}

class Cat implements Animal {

	@Override
	public String getName() {
		return "The Cat";
	}	
}

class Dog implements Animal {
	@Override
	public String getName() {
		return "The Dog";
	}	
}

class SimpleCash {
	public static void main(String[] args) {
		final List<String> simpleCash = new ArrayList<String>();
		simpleCash.add((new Cat().getName()));
		simpleCash.add((new Dog().getName()));
	}
}
...
Рейтинг: 0 / 0
20.01.2012, 18:35:52
    #37624642
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
смысл в Dynamic Proxy Classes
OOsalivanГде тут проблема?
При добавлении метода в Animal, кеширование для него само не появится. Для каждого нового метода нужно добавлять кеширование. Так?

Я имел ввиду полноценное кеширование. Упростите пример ниже через OOP

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
interface Animal {
	String getName();
	String getColor();
}

class Cat implements Animal {
	public String getName() {
                String name = Cache.get("name");
                if(name == null){
                       name = Repository.loadName("cat");
                       Cache.put("name", name);
                }
		return name;
	}	
	public String getColor() {
                String color= Cache.get("color");
                if(color== null){
                       name = Repository.loadColor("cat"));
                       Cache.put("color", color);
                }
		return color;
	}	
}

class Dog implements Animal {
	public String getName() {
                String name = Cache.get("name");
                if(name == null){
                       name = Repository.loadName("dog"));
                       Cache.put("name", name);
                }
		return name;
	}	
	public String getColor() {
                String color= Cache.get("color");
                if(color== null){
                       name = Repository.loadColor("dog");
                       Cache.put("color", color);
                }
		return color;
	}	
}
...
Рейтинг: 0 / 0
20.01.2012, 18:37:22
    #37624644
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
смысл в Dynamic Proxy Classes
А теперь добавь метод getSurName() для каждого наследника, и представь что тупоголовый заказчик хочет выводить имя в UPPER_CASE, тупой пример но иллюстративный
...
Рейтинг: 0 / 0
20.01.2012, 18:38:20
    #37624648
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
смысл в Dynamic Proxy Classes
У Blazkowicz пример лучше:)
...
Рейтинг: 0 / 0
20.01.2012, 18:41:40
    #37624655
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
смысл в Dynamic Proxy Classes
BlazkowiczУпростите пример ниже через OOP
Вариант уноса кэша на уровень репозитория не рассматриваем. Представим что все данные грузятся разными методами:
Repository.loadCatName();
Repository.loadDogName();
т.е. это разные источники данных, модифицировать которые не выйдет.
...
Рейтинг: 0 / 0
22.01.2012, 23:50:44
    #37626228
OOsalivan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
смысл в Dynamic Proxy Classes
BlazkowiczBlazkowiczУпростите пример ниже через OOP
Вариант уноса кэша на уровень репозитория не рассматриваем. Представим что все данные грузятся разными методами:
Repository.loadCatName();
Repository.loadDogName();
т.е. это разные источники данных, модифицировать которые не выйдет.

Могу предложить что ниже, но если принимать, что "все данные грузятся разными методами", то можно создать дополнительный енум с перечислением всех животных и впихнуть ветвление в switch case, правда это получиться не ООП. Но с другой стороны я не пойму каким образом нам облегчит код использование Dynamic Proxy?

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
abstract class AbstractAnimal implements Animal {

	protected abstract String getIdentityName();

	protected abstract String getIdentityColor();

	private enum Attribute {
		name, color
	}
	
	@Override
	public String getName() {
		return getCachedValue(AbstractAnimal.Attribute.name);
	}

	@Override
	public String getColor() {
		return getCachedValue(AbstractAnimal.Attribute.color);
	}

	private String getCachedValue(Attribute attr) {
		String value = Cache.get(attr.name());
		if (value == null) {
			switch (attr) {
			case name:
				value = Repository.loadName(getIdentityName());
				break;
			case color:
				value = Repository.loadColor(getIdentityColor());
				break;
			default:
				throw new IllegalArgumentException();
			}
		}
		Cache.put(attr.name(), value);
		return value;
	}
}

class CatImpl extends AbstractAnimal {

	@Override
	protected String getIdentityName() {
		return "cat";
	}

	@Override
	protected String getIdentityColor() {
		return "color";
	}
}

class DogImpl extends AbstractAnimal {

	@Override
	protected String getIdentityName() {
		return "dog";
	}

	@Override
	protected String getIdentityColor() {
		return "color";
	}
}
...
Рейтинг: 0 / 0
23.01.2012, 11:42:15
    #37626539
Miha_S7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
смысл в Dynamic Proxy Classes
OOsalivan,

отличие Dynamic Proxy от того варианта, который вы привели в том, что ваш вариант статичен. Вы получаете байт-код при компиляции и далее уже не можете его изменить. Пример:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
public intf_1 {
    void m1();
    void m2();
}

public intf_2 {
    void m1(int i);
    void m2(int i);
}

public class Cls1_1 implements intf_1 {
    void m1() {
        ...
    }
    void m2() {
        ...
    }
}
...
public class Cls1_m implements intf_1 {
    void m1() {
        ...
    }
    void m2() {
        ...
    }
}

public class Cls1_3 implements intf_n {
    void m1(int i) {
        ...
    }
    void m2(int i) {
        ...
    }
}
...
public class Cls1_k implements intf_n {
    void m1(int i) {
        ...
    }
    void m2(int i) {
        ...
    }
}



имеем 2 интерфейса и m и k их реализаций. Заранее не известно, объект какого типа нужно вернуть и с какими реализациями. Можно конечно написать класс у которого будут методы типа "getImplIntfss()", "getImplObj(Class<?> intf)", который будет при создании получать аргументы - классы интерфейсов, которые он реализует, и реализующие их объекты. Этот вариант не прозрачен и не удобен, потому что часто приходится состыковывать различные библиотеки, разработчики которых об этом классе ничего не знают. В случае же с DynamicProxy создаётся объект нового класса. Именно нового, так как создаётся новый байт код для этого класса. Так во всяком случае реализовано в OpenJDK. Далее этот объект можно прозрачно передавать куда угодно. И пользоваться всеми благами reflection и др. инструментами, как будто мы при написании кода определили именно этот класс который реализует только те интерфейсы, которые нам нужны и с теми реализациями, которые нам нужны. Ну и как ещё один плюс - дополнительный слой логики, который мы можем поместить при вызове всех методов прокси-объекта.
...
Рейтинг: 0 / 0
23.01.2012, 12:56:21
    #37626735
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
смысл в Dynamic Proxy Classes
OOsalivanМогу предложить что ниже, но если принимать, что "все данные грузятся разными методами", то можно создать дополнительный енум с перечислением всех животных и впихнуть ветвление в switch case, правда это получиться не ООП. Но с другой стороны я не пойму каким образом нам облегчит код использование Dynamic Proxy?

В вашем варианте при 10-20 методах доступа, соответственно такой же длины будет switch/case. И чем больше проект, тем больше этот метод. Причем полиморфизма там уже не может быть никак.

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

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
interface Animal {
	String getName();
	String getColor();
}

class Cat implements Animal {
	public String getName() {
		return Repository.loadName("cat");
	}	
	public String getColor() {
		return Repository.loadColor("cat");
	}	
}

class Dog implements Animal {
	public String getName() {
		return Repository.loadName("dog"));
	}	
	public String getColor() {
                return Repository.loadColor("dog");
	}	
}

class InvokationHandler...{
    public Object invoke(Object proxy, Method method, Object[] args)
	throws Throwable{
                String value = Cache.get(method);
                if(value == null){
                       value = method.invoke(instance, args);
                       Cache.put(method, value);
                }
		return value;

    }
...
Рейтинг: 0 / 0
23.01.2012, 12:57:51
    #37626739
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
смысл в Dynamic Proxy Classes
Miha_S7отличие Dynamic Proxy от того варианта, который вы привели в том, что ваш вариант статичен.
Да, очень верное замечание. OOSalivan реализовал статический прокси, который тоже имеет право на жизнь, если никакой возможности использовать AOP нет.
...
Рейтинг: 0 / 0
23.01.2012, 18:27:50
    #37627679
OOsalivan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
смысл в Dynamic Proxy Classes
Blazkowicz,

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
class InvokationHandler...{
    public Object invoke(Object proxy, Method method, Object[] args)
	throws Throwable{
                String value = Cache.get(method);
                if(value == null){
                       value = method.invoke(instance, args);
                       Cache.put(method, value);
                }
		return value;

    }



Разве это не тот же switch case придеться дописывать? Вызовы Repository.loadName, Repository.loadColor в коде выше не указанны. А switch case в том что я писал ранее именно разруливают когда какие методы Repository вызывать
...
Рейтинг: 0 / 0
23.01.2012, 18:40:03
    #37627709
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
смысл в Dynamic Proxy Classes
OOsalivanРазве это не тот же switch case придеться дописывать? Вызовы Repository.loadName, Repository.loadColor в коде выше не указанны. А switch case в том что я писал ранее именно разруливают когда какие методы Repository вызывать

method.invoke вызовет ту реализацию, которая написана у класса.
...
Рейтинг: 0 / 0
23.01.2012, 19:15:20
    #37627776
OOsalivan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
смысл в Dynamic Proxy Classes
BlazkowiczOOsalivanРазве это не тот же switch case придеться дописывать? Вызовы Repository.loadName, Repository.loadColor в коде выше не указанны. А switch case в том что я писал ранее именно разруливают когда какие методы Repository вызывать

method.invoke вызовет ту реализацию, которая написана у класса.

Т.е мы знаем что некий класс какимто образом реализет интерфейс (например Animal) и если мы хотим обернуть вызов метода String getName() в некий дополнительный код
Код: java
1.
2.
3.
4.
5.
                String value = Cache.get(method);
                if(value == null){
                       value = method.invoke(instance, args);
                       Cache.put(method, value);
                }


То в этом случае используем прокси?
...
Рейтинг: 0 / 0
24.01.2012, 11:14:21
    #37628445
Miha_S7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
смысл в Dynamic Proxy Classes
OOsalivan,

тут нужно подумать, для подобных целей есть ещё такая штука как декоратор. Всё зависит от задачи
...
Рейтинг: 0 / 0
24.01.2012, 11:35:36
    #37628484
OOsalivan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
смысл в Dynamic Proxy Classes
Miha_S7OOsalivan,

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

О чем я изначально в теме и говорю :

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
class Cat {
	
	public String getName() {
		return "cat";
	}
}

class CashCat extends Cat{
	
	@Override
	public String getName() {
		System.out.println("Start cashe");
		String name = super.getName();
		System.out.println("End cashe");
		return name;
	}
}
...
Рейтинг: 0 / 0
24.01.2012, 11:51:48
    #37628508
Miha_S7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
смысл в Dynamic Proxy Classes
OOsalivan,

ну сами подумайте, вам же уже писали, что декоратор и статичный код в некоторых случаях неудобен. Да, с помощью декораторов можно решить задачу, но придётся пихать один и тот же код(если это нужно) в каждый метод. И, использовать декоратор вы сможете только для заранее определённого набора интерфейсов и этот набор вы не сможете менять в рантайме, то есть код у вас будет статичный.
Dynamic Proxy Classes
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / смысл в Dynamic Proxy Classes / 23 сообщений из 23, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]