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

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

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

Зачем? Если у нас есть интерфейс с несколькими методами, то мы создаем только один класс с реализацией этих методов... Не понял зачем создавать несколько классов?
...
Рейтинг: 0 / 0
смысл в Dynamic Proxy Classes
    #37624524
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
OOsalivanЗачем? Если у нас есть интерфейс с несколькими методами, то мы создаем только один класс с реализацией этих методов... Не понял зачем создавать несколько классов?
Как вы будете выполнять один и тот же код в каждом методе? Копировать вызов утилитного метода в каждый метод реализации?
Proxy нужны не для того чтобы "реализовывать интерфейсы". Обычно, они проксируют конкретную реализацию интерфейса.
Пример. У вас есть интерфейс и две реализации. Результат работы каждого метода вам нужно поместить в кэш. Напишите как это будет выглядеть через ООП и полиморфизм.
...
Рейтинг: 0 / 0
смысл в Dynamic Proxy Classes
    #37624544
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Возможно у вас ещё возникло недопонимание из-за использования интерфейса. Это только ограничение Java Reflection. В реальной жизни Dynamic Proxy можно реализовать и на классе, без каких-либо интерфейсов.
...
Рейтинг: 0 / 0
смысл в Dynamic Proxy Classes
    #37624628
OOsalivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
смысл в Dynamic Proxy Classes
    #37624642
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
смысл в Dynamic Proxy Classes
    #37624644
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А теперь добавь метод getSurName() для каждого наследника, и представь что тупоголовый заказчик хочет выводить имя в UPPER_CASE, тупой пример но иллюстративный
...
Рейтинг: 0 / 0
смысл в Dynamic Proxy Classes
    #37624648
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У Blazkowicz пример лучше:)
...
Рейтинг: 0 / 0
смысл в Dynamic Proxy Classes
    #37624655
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczУпростите пример ниже через OOP
Вариант уноса кэша на уровень репозитория не рассматриваем. Представим что все данные грузятся разными методами:
Repository.loadCatName();
Repository.loadDogName();
т.е. это разные источники данных, модифицировать которые не выйдет.
...
Рейтинг: 0 / 0
смысл в Dynamic Proxy Classes
    #37626228
OOsalivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
смысл в Dynamic Proxy Classes
    #37626539
Miha_S7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
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
смысл в Dynamic Proxy Classes
    #37626735
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
смысл в Dynamic Proxy Classes
    #37626739
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Miha_S7отличие Dynamic Proxy от того варианта, который вы привели в том, что ваш вариант статичен.
Да, очень верное замечание. OOSalivan реализовал статический прокси, который тоже имеет право на жизнь, если никакой возможности использовать AOP нет.
...
Рейтинг: 0 / 0
смысл в Dynamic Proxy Classes
    #37627679
OOsalivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
смысл в Dynamic Proxy Classes
    #37627709
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
OOsalivanРазве это не тот же switch case придеться дописывать? Вызовы Repository.loadName, Repository.loadColor в коде выше не указанны. А switch case в том что я писал ранее именно разруливают когда какие методы Repository вызывать

method.invoke вызовет ту реализацию, которая написана у класса.
...
Рейтинг: 0 / 0
смысл в Dynamic Proxy Classes
    #37627776
OOsalivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
смысл в Dynamic Proxy Classes
    #37628445
Miha_S7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
OOsalivan,

тут нужно подумать, для подобных целей есть ещё такая штука как декоратор. Всё зависит от задачи
...
Рейтинг: 0 / 0
смысл в Dynamic Proxy Classes
    #37628484
OOsalivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
смысл в Dynamic Proxy Classes
    #37628508
Miha_S7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
OOsalivan,

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


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