Dynamiczne dodanie metody do klasy / Wrapper

Dynamiczne dodanie metody do klasy / Wrapper
1

Czesc,
Mam obiekt który muszę "wzbogacić" o dodatkowe pole (opakować go). Nie mogę ingerować w żaden sposób w kod obiektu który chcę rozbudować (ani w sposób jego tworzenia). Chciałbym żeby w przypadku gdy orginalny obiekt (ten ktory chce rozbudowac) zostanie zmieniony to żeby mój obiekt którym go opakuję miał wszystkie jego nowe metody bez zadnej interwencji z mojej strony. Macie jakiś pomysł (wzorzec projektowy), etc?

Shalom
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

Ale przecież w temacie sam sobie odpowiedziałeś. Z opisu rozumiem że chodzi ci o wzorzec Dekorator?


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
__krzysiek85
  • Rejestracja:ponad 18 lat
  • Ostatnio:ponad 9 lat
  • Postów:1019
0

Dekorator nie spełnia jednego wymagania - jeżeli do klasy opakowanej dojdzie nowa metoda, to w dekoratorze nie będzie ona automatycznie dostępna (trzeba ją dopisać).
Czy jednak tak silne wymaganie jest naprawdę konieczne?

Jeżeli tak, to możesz zastosować:

  1. Dziedziczenie
  2. http://docs.oracle.com/javase/6/docs/api/java/lang/reflect/Proxy.html

Registered Linux user #456405 | SCJP 6 | SCWCD 5 | SCBCD 5
edytowany 1x, ostatnio: __krzysiek85
Shalom
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

Faktycznie, nie zauważyłem tego wymagania. Jeśli musi tak być to raczej nie ma innej opcji niż Dziedziczenie albo pobieranie informacji o metodach z refleksji.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
0

Żeby użyć dekoratora to z klasy którą chcę dekorować muszę wyodrębnić interfejs. Ja nie mogę w żaden sposób ruszać kodu tej klasy

ŁF
Moderator
  • Rejestracja:ponad 22 lata
  • Ostatnio:6 dni
0

wiec dziedzicz zamiast opakowywać


0

W sumie byłoby to logiczne ale chyba zapomniałem wspomnieć o ważnej rzeczy. Nie może zmienić mi się sposób wywoływania kodu. Może przykład przybliży problem:

Kopiuj
 
class KlasaKtorejNieMogeZmieniac{
	private a;
	private b;
	
	String metodaA(){
		return a;
	}
	
	String metodaB(){
		return b;
	}
}

class KlasaPomocnicza extends KlasaKtorejNieMogeZmieniac{
	
	String metodaNowa(){
		return "Nowa";
	}
	
}

class C{
	Object metodaBiznesowa(){
		KlasaKtorejNieMogeZmieniac obj = invoke(...);//jakis kod dostarczajacy mi obiekt klasy "KlasaKtorejNieMogeZmieniac"
		//tutaj chciałbym zwrócić obiekt na którym mogę robić wywołania w identyczny sposób jakbym mniał obiekt KlasaKtorejNieMogeZmieniac (wowołuje przy pomocy refleksji)
		//takie metody:
		//obj.metodaA();
		//obj.metodaB();
		//Ale oprócz tego rownież
		//obj.metodaNowa();
	}
}
__krzysiek85
  • Rejestracja:ponad 18 lat
  • Ostatnio:ponad 9 lat
  • Postów:1019
0

Dziedziczenie odpada, gdyż nie kontrolujesz tworzenia obiektu.
http://docs.oracle.com/javase/6/docs/api/java/lang/reflect/Proxy.html odpada, gdyż KlasaKtorejNieMogeZmieniac nie wystawia swoich metod jako interfejsy.


Registered Linux user #456405 | SCJP 6 | SCWCD 5 | SCBCD 5
edytowany 1x, ostatnio: __krzysiek85
RI
  • Rejestracja:około 22 lata
  • Ostatnio:ponad 11 lat
0

Tak myślałem, ze to jest nie bardzo do zrobienia


edytowany 1x, ostatnio: riker
__krzysiek85
  • Rejestracja:ponad 18 lat
  • Ostatnio:ponad 9 lat
  • Postów:1019
0

Jedyna opcja to chyba zastosowanie bibliotek javassist lub CGLib.

np. javassist (zobacz punkt "4.3 Adding a new method or field"):
http://www.csg.is.titech.ac.jp/~chiba/javassist/tutorial/tutorial2.html


Registered Linux user #456405 | SCJP 6 | SCWCD 5 | SCBCD 5

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.