Proxy Dynamique en Golo
Golo est fait pour utiliser des classes Java. Si vous manipulez des classes qui implĂ©mentent des interfaces, il est tout Ă fait possible de âgrefferâ des comportements Ă vos mĂ©thodes de classes (celles dĂ©clarĂ©es dans une interface) grĂące Ă import java.lang.reflect.Proxy
. Voyons donc comment faire:
Imaginez une interface java âToonâ:
package org.k33g;
public interface Toon {
public String hello(String message);
public String speak(String message);
}
Imaginez une classe java qui implémente Toon
:
package org.k33g;
public class TinyToon implements Toon {
private String name = null;
public TinyToon(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String hello(String message) {
return "HELLO I'M "+this.name+" : "+ message;
}
@Override
public String speak(String message) {
return "BLABLA BY "+this.name+" : "+ message;
}
}
Proxy dynamique
Il est possible de créer un proxy de TinyToon
, implémentant donc Toon
et ce dynamiquement :
Ce peut ĂȘtre trĂšs pratique, si vous avez des traitements (mĂ©thodes) qui âattendentâ des objets de type Toon
, et que vous souhaitez ajouter des comportements aux mĂ©thodes (ce nâest possible que pour les mĂ©thodes dĂ©clarĂ©es dans lâinterface implĂ©mentĂ©e par la classe) :
Dans un 1er temps, si nous utilisons tout simplement TinyToon
:
import org.k33g.TinyToon
function main = |args| {
let toon = TinyToon("Babs")
println(toon:hello("HI !!!"))
println(toon:speak("IT'S SO CUTE"))
}
Nous obtiendrons Ă lâexĂ©cution la sortie suivante :
HELLO I'M Babs : HI !!!
BLABLA BY Babs : IT'S SO CUTE
Maintenant, nous allons créer notre proxy de TinyToon
:
Nous allons maintenant utiliser Proxy.newProxyInstance()
:
import java.lang.reflect.InvocationHandler
import java.lang.reflect.Proxy
import org.k33g.TinyToon
function main = |args| {
let toon = TinyToon("Babs")
let toonProxy = Proxy.newProxyInstance(
toon:getClass():getClassLoader(),
toon:getClass():getInterfaces(),
(|proxy, method, args...| {
println("You've called : " + method:getName())
let result = null
if method:getName() is "hello" {
println("hello from proxy")
result = toon:hello(args:get(0))
}
if method:getName() is "speak" {
println("speak from proxy")
result = toon:speak(args:get(0))
}
return result
}):to(InvocationHandler.class))
println(toonProxy:hello("HI !!!"))
println(toonProxy:speak("IT'S SO CUTE"))
}
Remarquez que nous âcastonsâ notre closure |proxy, method, args...| { ... }
en InvocationHandler
, en utilisant ():to(InvocationHandler.class)
.
Nous obtiendrons Ă lâexĂ©cution la sortie suivante :
You've called : hello
hello from proxy
HELLO I'M Babs : HI !!!
You've called : speak
speak from proxy
BLABLA BY Babs : IT'S SO CUTE
Et voilĂ , vous venez de faire de lâAOP avec Golo. Ce qui vous dĂ©montre une fois de plus la puissance de ce langage.
Vous trouverez ici une version âgĂ©nĂ©riqueâ rĂ©utilisable dâun proxy dynamique : https://github.com/k33g/DynoGolo.
42. ;)
Ă venir : comment modifier directement Golo. Stay tuned
Tweet