I am currently using EasyMock and creating mock objects like this
mockedObject = createMock(myInterface.class);
Easy mock is an unnecessary overhead(because the method that i mock is really simple) and i would like to create a mock without it.
But the problem is myInterface is an interface so how do i instantiate it.Please suggest.
Thanks,
Sriram
The easiest way would be to create an inner class that implements the interface, implement the methods to return the data that you want, then use it in the test case.
For example:
public void testMethod ( )
{
MyInterface mockObject = new MyInterface ( ) {
public void myMethod ( )
{
// NOOP
}
public int myFunction ( )
{
return -1 ;
}
}
// Proceed with the test case using mockObject
}
You can create and Anoymous class e.g.
MyInterface myMock = new MyInterface() {
... methods implemented here
};
If you need to verify the number of times a method is called you can add a simple counter member for each method.
e.g.
public void testMethod ( )
{
MyInterface mockObject = new MyInterface ( ) {
public int MyMethodCount = 0;
public int MyFunctionCount = 0;
public void myMethod ( )
{
MyMethodCount++;
// NOOP
}
public int myFunction ( )
{
MyFunctionCount++;
return -1 ;
}
}
// Proceed with the test case using mockObject
}
In the absence of a mock framework, java.lang.reflect.Proxy is your best bet. If you've never used it before, you can create a dynamic object which implements a set of interfaces, and you use the InvocationHandler to check each method call and decide what to do. This is a very powerful technique (and not limited to testing), as you can delegate method calls to other objects, etc.... It also insulates you from certain interface changes when you do this sort of delegation, as you don't declare each method. It adapts to the interface at runtine.
public static interface MyIntf {
String foo(String arg1);
}
InvocationHandler invocationHandler = new InvocationHandler() {
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals("foo") &&
method.getParameterTypes().length == 1 &&
method.getParameterTypes()[0] == String.class) {
// do your mocking here. For now i'll just return the input
return args[0];
}
else {
return null;
}
}
};
MyIntf myintf = (MyIntf) Proxy.newProxyInstance(getClass().getClassLoader(),
new Class[] { MyIntf.class },
invocationHandler);
System.out.println(myintf.foo("abc"));
You cannot instantiate an interface, you need to work with one of its implementation. Since you have decided to forgo EasyMock (not sure why), then you need to either instantiate one of the existing interfaces implementations, or create a new one just for testing.
Related
I'm writing an application where I need to implement functional interfaces on runtime. I don't know in advance which interfaces to implement, but can resolve the Method object using reflection from the interface's Class object.
For the purpose of simplifying the question, let's say that I'm passing a Function object containing the implementation of the method.
Straight-forward stuff:
#SuppressWarnings("unchecked")
private <T> T implement(Class<T> interfaceType, Method m, Function<Object[], ?> f) {
return (T) Proxy.newProxyInstance(
getClass().getClassLoader(),
new Class<?>[]{interfaceType},
(proxy, method, args) -> {
if (method.equals(m)) {
return f.apply(args);
}
// Calls to toString, hashCode, and equals go here.
throw new UnsupportedOperationException(method.getName());
}
);
}
So calls to toString, hashCode, and equals currently fail. I clearly don't want that.
From the docs of java.lang.reflect.Proxy:
An invocation of the hashCode, equals, or toString methods declared in java.lang.Object on a proxy instance will be encoded and dispatched to the invocation handler's invoke method in the same manner as interface method invocations are encoded and dispatched, as described above. The declaring class of the Method object passed to invoke will be java.lang.Object. Other public methods of a proxy instance inherited from java.lang.Object are not overridden by a proxy class, so invocations of those methods behave like they do for instances of java.lang.Object.
So I can override these methods however I want. That's cool, but I would prefer not to.
Sure, I could make dummy implementations that do more or less the same thing (except for hashCode which is native) or capture some other dummy object (maybe the invocation handler itself) and invoke the method on that one. But I feel like I should be able to just "fall through" to the methods inherited from java.lang.Object the usual way. Or in other words, call the equivalent of super.hashCode() etc. directly on proxy.
Is there a good/standard way of doing that?
Based on the suggestions in the comments, I ended up defining the following base invocation handler:
public class ObjectInvocationHandler implements InvocationHandler {
public static final Method HASH_CODE;
public static final Method EQUALS;
public static final Method TO_STRING;
static {
Class<Object> object = Object.class;
try {
HASH_CODE = object.getDeclaredMethod("hashCode");
EQUALS = object.getDeclaredMethod("equals", object);
TO_STRING = object.getDeclaredMethod("toString");
} catch (NoSuchMethodException e) {
// Never happens.
throw new Error(e);
}
}
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Exception {
// The clone() method is not handled as there's no way to emulate the behavior of that method.
// Implementers would have to implement cloning entirely in a subclass.
if (method.equals(HASH_CODE)) {
return objectHashCode(proxy);
}
if (method.equals(EQUALS)) {
return objectEquals(proxy, args[0]);
}
if (method.equals(TO_STRING)) {
return objectToString(proxy);
}
throw new UnsupportedOperationException(method.getName());
}
public String objectClassName(Object obj) {
return obj.getClass().getName();
}
public int objectHashCode(Object obj) {
return System.identityHashCode(obj);
}
public boolean objectEquals(Object obj, Object other) {
return obj == other;
}
public String objectToString(Object obj) {
return objectClassName(obj) + '#' + Integer.toHexString(objectHashCode(obj));
}
}
Then the proxy is then created using
Proxy.newProxyInstance(
interfaceType.getClassLoader(),
new Class<?>[]{interfaceType},
new ObjectInvocationHandler() {
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Exception {
if (method.equals(m)) {
return f.apply(args);
}
return super.invoke(proxy, method, args);
}
}
)
I was wondering, what if I have the following case:
public class MyObject<T> {
private T myTObject;
public void setMyTObject(T m) {
myTObject = m;
}
public T getMyTObject() {
return myTObject;
}
}
And now I want that class to react something like these:
MyObject<ObjectA> objA = new MyObject<ObjectA>();
ObjectA objAInstance = objA.getObjectA();
or
objA.setObjectA(otherObjectAInstance);
Is there a way to dynamically create methods based on T class name?
Or should I better extend ObjectA to MyObject and create those methods using super.get/seMyObject()?
For clarification:
The idea is to have a getter and setter method generated dynamically
so, if I create an instance of:
MyObject<A> objA = new MyObject<A>();
I would be able to call method:
objA.getA();
getA() will call internally getMyTObject() or just return myTObject
so MyObject may react based on T class and generate the corresponding method.
I have updated member attribute to differentiate from MyObject class, it may lead to confusion. also fixed Method return and parameter Type.
Update Answer is completely changed.
Sounds like you want to use something through reflection. The problem with truly dynamically generating the method names is that, as others have commented, it would have to be done in bytecode which means that other classes trying to use your dynamic classes don't have Java code to refer to. It can be done, but it would be a mess.
Instead, here's a possible solution using generics. Please note that this is something of a quick and dirty hack; I leave it to you to refine it. You define an interface with the getters and setters you want, with whatever you want them named:
package com.example.dcsohl;
public interface IntegerWrapper {
public Integer getInteger();
public void setInteger(Integer i);
}
And then, to use them, you use this class to do the heavy lifting. Note that the error checking isn't very good; for example, it doesn't check that "getFoo" at all corresponds to the name of the class being passed in; nor does it validate that the "foo" in "getFoo" matches the "setFoo" method. This is something you can improve on.
package com.example.dcsohl;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyWrapper<T> implements InvocationHandler {
Class<T> clazz = null;
T myvalue = null;
public static <W,T> W getInstance(Class<W> clazz, Class<T> clazz2) {
ProxyWrapper<T> wrapper = new ProxyWrapper<T>();
wrapper.setClass(clazz2);
#SuppressWarnings("unchecked")
W proxy = (W)Proxy.newProxyInstance(clazz.getClassLoader(), new Class[] {clazz}, wrapper);
return proxy;
}
private void setClass(Class<T> clazz) {
this.clazz = clazz;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// getter has no arguments
if (method.getName().startsWith("get") && (args == null || args.length == 0)) {
return myvalue;
} else if (method.getName().startsWith("set") && args.length == 1) {
Object o = args[0];
if (o.getClass().isAssignableFrom(clazz)) {
#SuppressWarnings("unchecked")
T val = (T)o;
myvalue = val;
return null;
}
} else {
throw new Exception();
}
return null;
}
}
Finally, to use it, here's a quick sample:
package com.example.dcsohl;
public class Main {
public static void main(String[] args) {
Integer foo = 5;
IntegerWrapper wrapper = ProxyWrapper.getInstance(IntegerWrapper.class, Integer.class);
wrapper.setInteger(foo);
Integer bar = wrapper.getInteger();
System.out.println(bar);
}
}
It seems like a lot of work just to avoid writing simple wrapper classes, and you'd be right, but reflection has its uses, and this is something of a sampler.
Say I have a class with many of public methods:
public class MyClass {
public void method1() {}
public void method2() {}
(...)
public void methodN() {}
}
Now I would like to create a wrapper class which would delegate all the methods to wrapped instance (delegate):
public class WrapperClass extends MyClass {
private final MyClass delegate;
public WrapperClass(MyClass delegate) {
this.delagate = delegate;
}
public void method1() { delegate.method1(); }
public void method2() { delegate.method2(); }
(...)
public void methodN() { delegate.methodN(); }
}
Now if MyClass has a lot of methods I would need to override each of them which is more or less the same code which just "delegates". I was wondering if it is possible to do some magic to automatically call a method in Java (so the Wrapper class would need to say "Hey if you call a method on me just go to delegate object and call this method on it).
BTW: I can not use inheritance because the delegate is not under my control.I just get its instance from elsewhere (another case would be if MyClass was final).
NOTE: I do not want IDE generation. I know I can do it with help of IntelliJ/Eclipse, but I'm curious if this can be done in code.
Any suggestions how to achieve something like this? (NOTE: I would probably be able to do it in some scripting languages like php where I could use php magic functions to intercept the call).
Perhaps the dynamic Proxy of java can help you. It only works if you consequently use interfaces. In this case, I will call the interface MyInterface and set up a default implementation:
public class MyClass implements MyInterface {
#Override
public void method1() {
System.out.println("foo1");
}
#Override
public void method2() {
System.out.println("foo2");
}
#Override
public void methodN() {
System.out.println("fooN");
}
public static void main(String[] args) {
MyClass wrapped = new MyClass();
wrapped.method1();
wrapped.method2();
MyInterface wrapper = WrapperClass.wrap(wrapped);
wrapper.method1();
wrapper.method2();
}
}
The wrapper class implementation would look like:
public class WrapperClass extends MyClass implements MyInterface, InvocationHandler {
private final MyClass delegate;
public WrapperClass(MyClass delegate) {
this.delegate = delegate;
}
public static MyInterface wrap(MyClass wrapped) {
return (MyInterface) Proxy.newProxyInstance(MyClass.class.getClassLoader(), new Class[] { MyInterface.class }, new WrapperClass(wrapped));
}
//you may skip this definition, it is only for demonstration
public void method1() {
System.out.println("bar");
}
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Method m = findMethod(this.getClass(), method);
if (m != null) {
return m.invoke(this, args);
}
m = findMethod(delegate.getClass(), method);
if (m != null) {
return m.invoke(delegate, args);
}
return null;
}
private Method findMethod(Class<?> clazz, Method method) throws Throwable {
try {
return clazz.getDeclaredMethod(method.getName(), method.getParameterTypes());
} catch (NoSuchMethodException e) {
return null;
}
}
}
Note that this class:
extends MyClass, to inherit a default implementation (any other would do)
implements Invocationhandler, to allow the proxy to do reflection
optionally implement MyInterface (to satisfy the decorator pattern)
This solution allows you to override special methods, but to delegate all others. This will even work with sub classes of Wrapper class.
Note that the method findMethod does not yet capture the special cases.
This question is 6 months old already and #CoronA's wonderful answer has satisfied and been accepted by #walkeros, but I thought I would add something here as I think this can be pushed an extra step.
As discussed with #CoronA in the comments to his answer, instead of having to create and maintain a long list of MyClass methods in WrapperClass (i.e. public void methodN() { delegate.methodN(); }), the dynamic proxy solution moves this to the interface. The issue is that you still have to create and maintain a long list of signatures for the MyClass methods in the interface, which is perhaps a bit simpler but doesn't completely solve the problem. This is especially the case if you don't have access to MyClass in order to know all the methods.
According to Three approaches for decorating your code,
For longer classes, a programmer must choose the lesser of two evils:
implement many wrapper methods and keep the type of decorated object
or maintain a simple decorator implementation and sacrifice retaining
the decorated object type.
So perhaps this is an expected limitation of the Decorator Pattern.
#Mark-Bramnik, however, gives an fascinating solution using CGLIB at Interposing on Java Class Methods (without interfaces). I was able to combine this with #CoronaA's solution in order to create a wrapper that can override individual methods but then pass everything else to the wrapped object without requiring an interface.
Here is MyClass.
public class MyClass {
public void method1() { System.out.println("This is method 1 - " + this); }
public void method2() { System.out.println("This is method 2 - " + this); }
public void method3() { System.out.println("This is method 3 - " + this); }
public void methodN() { System.out.println("This is method N - " + this); }
}
Here is WrapperClass which only overrides method2(). As you'll see below, the non-overridden methods are, in fact, not passed to the delegate, which can be a problem.
public class WrapperClass extends MyClass {
private MyClass delagate;
public WrapperClass(MyClass delegate) { this.delagate = delegate; }
#Override
public void method2() {
System.out.println("This is overridden method 2 - " + delagate);
}
}
Here is MyInterceptor which extends MyClass. It employs the proxy solution using CGLIB as described by #Mark-Bramnik. It also employs #CononA's method of determining whether or not to send the method to the wrapper (if it is overridden) or the wrapped object (if it is not).
import java.lang.reflect.Method;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class MyInterceptor extends MyClass implements MethodInterceptor {
private Object realObj;
public MyInterceptor(Object obj) { this.realObj = obj; }
#Override
public void method2() {
System.out.println("This is overridden method 2 - " + realObj);
}
#Override
public Object intercept(Object arg0, Method method, Object[] objects,
MethodProxy methodProxy) throws Throwable {
Method m = findMethod(this.getClass(), method);
if (m != null) { return m.invoke(this, objects); }
Object res = method.invoke(realObj, objects);
return res;
}
private Method findMethod(Class<?> clazz, Method method) throws Throwable {
try {
return clazz.getDeclaredMethod(method.getName(), method.getParameterTypes());
} catch (NoSuchMethodException e) {
return null;
}
}
}
Here is Main and the results you get if you run it.
import net.sf.cglib.proxy.Enhancer;
public class Main {
private static MyClass unwrapped;
private static WrapperClass wrapped;
private static MyClass proxified;
public static void main(String[] args) {
unwrapped = new MyClass();
System.out.println(">>> Methods from the unwrapped object:");
unwrapped.method1();
unwrapped.method2();
unwrapped.method3();
wrapped = new WrapperClass(unwrapped);
System.out.println(">>> Methods from the wrapped object:");
wrapped.method1();
wrapped.method2();
wrapped.method3();
proxified = createProxy(unwrapped);
System.out.println(">>> Methods from the proxy object:");
proxified.method1();
proxified.method2();
proxified.method3();
}
#SuppressWarnings("unchecked")
public static <T> T createProxy(T obj) {
Enhancer e = new Enhancer();
e.setSuperclass(obj.getClass());
e.setCallback(new MyInterceptor(obj));
T proxifiedObj = (T) e.create();
return proxifiedObj;
}
}
>>> Methods from the unwrapped object:
This is method 1 - MyClass#e26db62
This is method 2 - MyClass#e26db62
This is method 3 - MyClass#e26db62
>>> Methods from the wrapped object:
This is method 1 - WrapperClass#7b7035c6
This is overridden method 2 - MyClass#e26db62
This is method 3 - WrapperClass#7b7035c6
>>> Methods from the proxy object:
This is method 1 - MyClass#e26db62
This is overridden method 2 - MyClass#e26db62
This is method 3 - MyClass#e26db62
As you can see, when you run the methods on wrapped you get the wrapper for the methods that are not overridden (i.e. method1() and method3()). When you run the methods on proxified, however, all of the methods are run on the wrapped object without the pain of having to delegate them all in WrapperClass or put all of the method signatures in an interface. Thanks to #CoronA and #Mark-Bramnik for what seems like a pretty cool solution to this problem.
Check the #Delegate annotation from Lombok framework:
https://projectlombok.org/features/Delegate.html
Switch to Groovy :-)
#CompileStatic
public class WrapperClass extends MyClass {
#Delegate private final MyClass delegate;
public WrapperClass(MyClass delegate) {
this.delagate = delegate;
}
//Done. That's it.
}
http://mrhaki.blogspot.com/2009/08/groovy-goodness-delegate-to-simplify.html
You don't have to do this -- your Wrapper class is a subclass of the original class, so it inherits all of its publicly accessible methods -- and if you don't implement them, the original method will be called.
You shouldn't have extends Myclass together with a private MyClass object -- that's really really redundant, and I can't think of a design pattern where doing that is right. Your WrapperClass is a MyClass, and hence you can just use its own fields and methods instead of calling delegate.
EDIT: In the case of MyClass being final, you'd be circumventing the willfull declaration to not allow subclassing by "faking" inheritance; I can't think of anyone willing to do that other than you, who is in control of WrapperClass; but, since you're in control of WrapperClass, not wrapping everything you don't need is really more than an option -- it's the right thing to do, because your object is not a MyClass, and should only behave like one in the cases you mentally considered.
EDIT you've just changed your question to mean something completely different by removing the MyClass superclass to your WrapperClass; that's a bit bad, because it invalidates all answers given so far. You should have opened another question.
Credits go to CoronA for Pointing out the Proxy and InvocationHandler classes. I worked out a more reusable utility class based on his solution, using generics:
public class DelegationUtils {
public static <I> I wrap(Class<I> iface, I wrapped) {
return wrapInternally(iface, wrapped, new SimpleDecorator(wrapped));
}
private static <I> I wrapInternally (Class<I> iface, I wrapped, InvocationHandler handler) {
return (I) Proxy.newProxyInstance(wrapped.getClass().getClassLoader(), new Class[] { iface }, handler);
}
private static class SimpleDecorator<T> implements InvocationHandler {
private final T delegate;
private SimpleDecorator(T delegate) {
this.delegate = delegate;
}
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Method m = findMethod(delegate.getClass(), method);
if (m == null) {
throw new NullPointerException("Found no method " + method + " in delegate: " + delegate);
}
return m.invoke(delegate, args);
}
}
private static Method findMethod(Class<?> clazz, Method method) throws Throwable {
try {
return clazz.getDeclaredMethod(method.getName(), method.getParameterTypes());
} catch (NoSuchMethodException e) {
return null;
}
}
}
Test it:
public class Test {
public interface Test {
public void sayHello ();
}
public static class TestImpl implements Test {
#Override
public void sayHello() {
System.out.println("HELLO!");
}
}
public static void main(String[] args) {
Test proxy = DelegationUtils.wrap(Test.class, new TestImpl());
proxy.sayHello();
}
}
I wanted to create an automatic delegation class that executes the delegatee's methods on the EDT. With this class, you just create a new utility method that will use an EDTDecorator, in which the implementation will wrap m.invoke in a SwingUtilities.invokeLater.
However, if I reflect on this, I may want to reconsider making a non-Reflection based proxy per interface that I have - it might be cleaner and faster, and more understandable. But, it's possible.
Define a method in WrapperClass i.e. delegate() that returns the instance of MyClass
OR
You can use reflection to do that but the caller has to pass the method name as an argument to an exposed method. And there will be complications regarding the method arguments/overloaded methods etc.
BTW: I can not use inheritance because the delegate is not under my control.I just get its instance from elsewhere (another case would be if MyClass was final)
The code that you have posted has public class WrapperClass extends MyClass
Actually your current implementation of WrapperClass is actually a decorator on top of MyClass
Let me redefine the problem for a specific case.
I want to override the close method of ResultSet interface in jdbc. My aim is to close the preparedstatement in close method of result set. I could not access to the Class (DelegatingResultSet) that implements in ResultSet interface. There are a lot of methods in ResultSet interface and overriding them one by one and calling the corresponding method from the ResultSet object is one solution. For a dynamic solution I used Dynamic ProxyClasses (https://docs.oracle.com/javase/1.5.0/docs/guide/reflection/proxy.html).
// New ResultSet implementation
public class MyResultSet implements InvocationHandler {
ResultSet rs;
PreparedStatement ps;
private Method closeMethod;
public MyResultSet(ResultSet rs, PreparedStatement ps) {
super();
this.rs = rs;
this.ps = ps;
try {
closeMethod = ResultSet.class.getMethod("close",null);
} catch (NoSuchMethodException | SecurityException e) {
e.printStackTrace();
}
}
public void close() {
try {
rs.close();
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static Object newInstance(ResultSet rs, PreparedStatement ps) {
return java.lang.reflect.Proxy.newProxyInstance(rs.getClass().getClassLoader(), rs.getClass().getInterfaces(),
new MyResultSet(rs,ps));
}
public Object invoke(Object proxy, Method m, Object[] args)
throws Throwable {
Object result = null;
try {
Class declaringClass = m.getDeclaringClass();
if (m.getName().compareTo("close")==0) {
close();
} else {
result = m.invoke(rs, args);
}
} catch (InvocationTargetException e) {
throw e.getTargetException();
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
} finally {
}
return result;
}
}
// How to call it:
ResultSet prs = (ResultSet) MyResultSet.newInstance(rs,ps);
I really appreciated #CoronA's answer. I also looked at #Mark Cramer's answer, but, if I'm not missing something, I think that there are always at least two instances of the "proxified" class with a strange relationship beteen the two objects.
This, along with the fact that cglib is now deprecated, pushed me to find a new implementation based on ByteBuddy.
This is what I came up with:
public class MyClass {
public String testMethod() {
return "11111";
}
public String testMethod2() {
return "aaaaa";
}
}
public class MyClassWithDelegate extends MyClass {
private static final Constructor<? extends MyClassWithDelegate> CONSTRUCTOR_WITH_DELEGATE;
static {
Constructor<? extends MyClassWithDelegate> temp = null;
try {
final var instrumentedMyClassWithDelegateType =
new ByteBuddy()
.subclass(MyClassWithDelegate.class)
.method(ElementMatchers.any())
.intercept(MethodDelegation.to(MethodInterceptor.class))
.make()
.load(MyClassWithDelegate.class.getClassLoader())
.getLoaded();
temp = instrumentedMyClassWithDelegateType.getConstructor(MyClass.class);
} catch (final Exception e) {
LOGGER.error("Cannot instrument class {}", MyClassWithDelegate.class, e);
}
CONSTRUCTOR_WITH_DELEGATE = temp;
}
public static MyClassWithDelegate getInstanceWithDelegate(final MyClass myClass) {
try {
return CONSTRUCTOR_WITH_DELEGATE.newInstance(myClass);
} catch (final Exception e) {
LOGGER.error("Cannot get instance of {}", MyClassWithDelegate.class, e);
throw new IllegalStateException();
}
}
private final boolean initialized;
private final MyClass delegate;
public MyClassWithDelegate(final MyClass delegate) {
super();
this.delegate = delegate;
this.initialized = true;
}
public String testMethod() {
return "22222";
}
public static class MethodInterceptor {
#RuntimeType
public static Object intercept(#This final MyClassWithDelegate self,
#Origin final Method method,
#AllArguments final Object[] args,
#SuperMethod final Method superMethod) throws Throwable {
if (!self.initialized || method.getDeclaringClass().equals(MyClassWithDelegate.class)) {
return superMethod.invoke(self, args);
} else {
return method.invoke(self.delegate, args);
}
}
}
}
The initialized field is used to prevent method calls the super constructor from being redirected to the delegate before its assignment (in this case it wouldn't be a problem, but I wanted to create a generic solution).
Every method called on an instance of MyClassWithDelegate will be redirected to the delegate, except from methods declared inside MyClassWithDelegate itself.
In this example, calling testMethod() on an instance of MyClassWithDelegate will return "22222", while testMethod2() will return "aaaaa".
Obviously, the delegation will actually work only if every instance of MyClassWithDelegate is obtained calling the getInstanceWithDelegate factory method.
I have an interface which has only one method. I have a static function which receives objects (these objects implement the interface), and I want to override/replace implementation of the method, that is defined in the interface, in objects. What is the best way to do this in Java
public class MyClass {
public interface MyInterface {
Object myMethod (Object blah);
}
public static MyInterface decorator(MyInterface obj) {
//I want to return a version of obj
//with a different implementation of myMethod
//everything else in obj should be same, except myMethod
}
}
You can create a class with the same interface that delegates all the methods calls yo your object, then you create an anonymous class extending it and override whatever you want
Intercace:
Interface MyInterface {
void m1();
void m2();
}
Delegating class:
class MyDelegate implements MyInterface {
private MyInterface delegate;
MyDelegate(MyInterface delegate) {
this.delegate = delegate;
}
void m1() {
delegate.m1();
}
void m2() {
delegate.m2();
}
}
In the static method you create an instance of an anonymous class extending MyDelegate and override whatever you want, the rest will be run by obj
static MyInterface wrap(MyInterface obj) {
return new MyDelegate(obj) {
void m1() {
// overrided m1
}
// my will eventually get to obj
};
}
You can't do that generally, without the knowledge of the exact object type you are decorating. If you know it, then you can create a subclass of that particular class with the implementation changed. Java's type system just isn't flexible enough to mix and match interface implementation like you need.
You could resort to dynamic class definition techniques, which would create a dynamic proxy for every object you pass into your decorate method, but there's an order of magnitude more complexity in such an approach.
Such kind of dynamic behavior is not directly supported in Java. But you can achieve something like this when the object cooperates. I.e. it could provide a method to change the implementation of myMethod:
void changeMethod(MyInterface other) {
realImpl = other;
}
Object myMethod (Object obj) {
return realImpl.myMethod(obj);
}
Using CGLib you can implements interfaces at runtime.
Example -
public class KeySample {
private interface MyFactory {
public Object newInstance(int a, char[] b, String d);
}
public static void main(String[] args) {
MyFactory f = (MyFactory)KeyFactory.create(MyFactory.class);
Object key1 = f.newInstance(20, new char[]{ 'a', 'b' }, "hello");
Object key2 = f.newInstance(20, new char[]{ 'a', 'b' }, "hello");
Object key3 = f.newInstance(20, new char[]{ 'a', '_' }, "hello");
System.out.println(key1.equals(key2));
System.out.println(key2.equals(key3));
}
}
You are looking for a dynamic proxy if we can restrict it to interfaces (any number of them).
So your problem: If you call the method in that interface first without calling the decorator and then with the decorator you want different behavior, so given this interface implementation:
MyInterface o = new MyInterface() {
public Object myMethod(Object blah) {
return "bar";
}
};
This should do different things, for example alter the return value (and/or something else):
System.out.println(o.myMethod(null));
o = decorator(o);
System.out.println(o.myMethod(null));
Output:
bar
foo
This can be done with a dynamic proxy in java:
public static MyInterface decorator(final MyInterface obj) {
InvocationHandler handler = new InvocationHandler() {
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals("myMethod")) {
//do something special
return "foo";
}
return method.invoke(obj, args);
}
};
MyInterface proxy = (MyInterface) Proxy.newProxyInstance(
MyInterface.class.getClassLoader(),
obj.getClass().getInterfaces(), //all or limit it to just one or a few
handler);
return proxy;
}
Update:
If you want to involve more interfaces (updated proxy instance code above to get the interfaces implemented instead of hard coding it):
Now makes this work:
public static void main(String[] args) {
A o = new A();
System.out.println(o.myMethod(null));
System.out.println(o.myOtherMethod(1));
Object o2 = decorator(o);
System.out.println(((MyInterface) o2).myMethod(null));
System.out.println(((MyInterface2) o2).myOtherMethod(1));
}
With output:
bar
2
foo <-- changed
2 <- the same behavior
Given:
class A implements MyInterface, MyInterface2 {
#Override
public Object myMethod(Object blah) {
return "bar";
}
#Override
public int myOtherMethod(int a) {
return a+1;
}
}
I have similar fun task from my university. For example, there is ClassA. I need to limit access to object that if today is sunday client can't make ClassA object or using existing ClassA objects. I think I need to make some wrapper for class because otherwise I need to make checking conditiong of day in each method of ClassA. Is there any desing patters for it? Please, I hope you can help me.
Factory pattern is what you are looking for. You pass the arguments to a factory class (the "wrapper") and it takes care of creating the right kind of object. For example:
class ClassA implements MyInterface { ... }
class ClassB implements MyInterface { ... }
class MyFactory {
public MyInterface create(int dayOfTheWeek) {
if (dayOfTheWeek == 0) {
return new ClassA();
} else {
return new ClassB();
}
}
}
When you need a new object, MyFactory decides the actual class:
MyFactory factory = new MyFactory();
MyInterface object = factory.create(dayOfTheWeek);
...
Since you want a client that cannot use other existing ClassA objects too, it would probably help a kind of dynamic proxy. Here the rough code:
public class MasterControl {
public static boolean check(Method m){
//do controls on the current day
//return true/false accordingly
}
}
public class ProxyFactory {
public static ClassAInterface getListProxy(final ClassA cp){
return (ClassAInterface) Proxy.newProxyInstance(cp.getClass().getClassLoader(), new Class[] {ClassAInterface.class},new InvocationHandler() {
#Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if(MasterControl.check(method,args[0]))
return method.invoke(cp, args);
else
return (ClassAInterface) null;
}
});
}
}
Factory pattern will help you to achieve this functionality.