I have long used reflection to decouple modules from "handlers".
I have a code base which is architected like this :
static enum AnimalHandlers {
Dog(Dog.class),
Cat(Cat.class);
private final Class c;
AnimalHandlers(Class class)
{
this.c=class;
}
public Class getAnimalHandler()
{
return c;
}
}
Then later in my code, I have a method which takes an "Animal" enum as input and uses reflection (that is, it gets the class from the enum and invokes "newInstance") to invoke the necessary handler.
I think the solution would be cleaner with Guice. How can I get rid of the enum/reflection and simply use guice to "hydrate" my control module with domain specific logic handlers?
You could well use a MapBinder<AnimalEnum, AnimalHandler>, and define a binding for each possible AnimalEnum value.
I think that there must be a better pattern here. I'm a little confused as to just how the Animal enum interfaces with the handler but I'll make some general suggestions and maybe one will stick.
I assume that there is no way to define the handlers in the Animal enum and you want to decouple the classes. Fine.
Could the the handlers register themselves with Animal.setHandler(...)? Then you could just call Animal.Dog.getHandler() to get Dog's handler.
I agree with #jfpoilpret that some sort of AnimalHandlerMapper would also be better. I assume there a common interface is possible, even if it just a marker interface.
Code:
private static Map<Animal, AnimalHandler> handlerMap
= new HashMap<Animal, AnimalHandler>();
static {
Dog dog = new Dog();
handlerMap.put(Animal.Dog, dog);
// we use the same handler twice here
handlerMap.put(Animal.Wolf, dog);
handlerMap.put(Animal.Cat, new Cat());
// do a Animal.values loop at the end to verify that everyone has a handler
}
public static AnimalHandler getHandler(Animal animal) {
return handlerMap.get(animal);
}
If for some reason you can't use the handler instances then I would do the same thing but with handler factories. So you've call handlerMap.get(animal).create(animal) or some such. This would be much cleaner than using reflection.
I'm not sure how Guice compares to Spring but if this was spring I would instantiate the handler beans and they would register with the AnimalHandlerMapper to completely decouple it.
Hope this helps.
Related
If I want to read some JSON into an object, and I have the interface but must use the Spring context to get the implementation class, I need to use a SimpleAbstractTypeResolver to map the interface to the implementation. So far, so good, if I know in advance what interfaces go to what implementation. But if the interface has methods that return other interfaces--and possibly down the line recursively--and I don't necessarily know in advance, I thought I could use reflection to figure it out. So this is what I came up with, but the compiler does NOT like the line resolver.addMapping(method.getReturnType(), method.getReturnType());, says it's not applicable for these arguments. I'm pretty sure the types are okay for that method--any thoughts on how to make this happen?
for (Method method : clazz.getMethods()) {
if (method.getReturnType().isInterface() && method.getName().startsWith("get")) {
// getter method returns an interface so find its implementation class
Class beanClass = context.getBean(method.getReturnType()).getClass();
if (clazz.isAssignableFrom(beanClass)) {
resolver.addMapping(method.getReturnType(), method.getReturnType());
mapInterfaces(objectMapper, clazz, resolver);
}
}
}
Probably you need to review your types.
My guess is following:
resolver.addMapping(method.getReturnType(), beanClass);
(replace second parameter method.getReturnType() with beanClass)
or as an alternative (the code is not completely clear for me, sorry)
resolver.addMapping(clazz, beanClass);
You should put an Interface and Implementation into addMapping().
Example:
interface ITest{};
class TestImpl implements ITest {}
usage:
resolver.addMapping(ITest.class, TestImpl.class);
Probably you need to review your types.
My guess is following:
new ObjectMapper().writerFor(<Interface>.class).writeValuesAsArray(<Class>);
I am new with design pattern, and I don't know which I have to apply in this case.
I have some data in a file, so I have to model that data and then start a class with that data.
For the reading of the file and the modeling I choose to apply the Dao pattern, so there is interface (Interface) and his implementation (InterfaceImplementation) that read the file and return the model data (DataModel).
After I have to instantiate another class (Runner) with that model data e call one of its method.
This is what I have done:
public class Factory {
public void start() {
Interface dao = new InterfaceImplementation();
DataModel data = dao.getDataModel();
Runner runner = new Runner(data);
runner.run();
}
}
So the client call only the method new Factory().start().
I have some doubts about this solution, I don't think this is a good solution and a good applying of the Factory pattern.
I hope to have been clean, cheers.
Your Factory class is actually not an implementation of the Factory creational pattern. It is an implementation of the Facade pattern.
Your Factory class's purpose is not only to simplify the instantiation process of a Runner, but to simplify the entire process of starting a Runner which makes it more than a factory.
On a side note, naming things is one of the most important aspect in programming. Choose meaningful names of the Ubiquitous Language of your domain.
public class Factory {
public void start() {
Interface dao = new InterfaceImplementation();
DataModel data = dao.getDataModel();
Runner runner = new Runner(data);
runner.run();
}
}
2 remarks :
A factory creates an object and generally provides a instance of that. Which looks like more to a factory in your code is :
DataModel data = dao.getDataModel();
Why re-instantiate InterfaceImplementation at each start() call ?
If you have multiple DataModels, a useful factory could by example create/retrieve a specific DataModel for clients.
public class DataModelFactory {
private Interface dao = new InterfaceImplementation();
public DataModel GetDataModelXXX() {
DataModel dataModel = dao.getDataModelXXX();
return dataModel ;
}
public DataModel GetDataModelYYY() {
DataModel dataModel = dao.getDataModelYYY();
return dataModel ;
}
}
A factory is intented to ease the creation of an object. In a factory after the creation the object will be returned.
So create the Runner and give it back to the caller.
There you can decide next what to do with it.
Its also important to give the method meaningful names.
The thing that caught my attention: in your current implementation, your client is "kinda" completely decoupled from all other activities. But not in a positive way.
Your client code calls start(); and then internally, a lot of things happen. But there is not even a return value from that method.
I am wondering now: how would any of this have an "lasting" effect on your system? Are there some implicit side effects; like that Runner updating some global state singleton somewhere?
In other words: given your code, what would happen if start() is called multiple times?! Or ... zero times?!
In that sense, it is not at all clear to me how this code "relates" to anything else. And well, that looks like a problem to me that you should look into.
( and yes, I understand that my input is more of a "code/design review" than a real answer; but heck, maybe it can be helpful )
Is there a way to modify class instance in Java? For example I want to provide custom callback method.
How is it possible to provide separate method/context/scope for each instance of a class?
In javascript it's easy to modify an existing class. It's easy to pass an anonymous function as callback to any method as well. With it's context and scope.
Or do I have to extend my custom class for every request if I need a different callback?
You can do it on instantiation like:
Whatever w = new Whatever("Something") {
public void onWhateverDoThis() {
//...
}
};
So where I personally used it recently were callback methods of a modal:
ModalManager.show(new Modal("Title", "Text") {
public void onDismiss() {
//Do something on dismiss
}
public void onConfirm() {
//Do something on confirm
}
});
Java and Javascript are very different languages. You'll be very frustrated if you try to apply to one a programming paradigm that works in the other. I too was very frustrated with Javascript at the beginning, coming from Java, until I understood the fundamental differences between dynamic and static languages.
In this particular case I don't think it's a good idea to extend your class every time you need to use a different callback, as it would result in a large number of subclasses. If you need a lot of objects that differ only on a particular aspect, wouldn't it be better to have a class or interface that represents that particular aspect?
A possible solution (but not the only correct one by any means) would be to use the Strategy pattern: define an interface that represents a callback and implement the interface for every different callback you need. You can then pass those callbacks as parameters just as you do in Javascript, with the exception that those callbacks won't be able to access any non-public member of the class that calls them.
Also be sure to take a look at the Apache Commons Functor library, which is essentially about having objects that represent functions. I've never used it but, being Apache Commons, it sure would be my first stop if I had your requirements.
You can get frustrated easily, due classic nonfunctional Java is not for those run time goals you have mentioned.
But indeed, you can implement callback in java by using an interface like this:
Ref: CALLBACK PATTERN IN JAVA ENVIRONMENT
For example, suppose you want to be notified when an event happens.
You can define an interface like this:
public interface SomeEvent{
// A regular method, it can return something or take arguments
public void someEventMethod();
}
Then, define a class that will signal/notify the event, It needs to expect objects that implement the SomeEvent interface and then invoke the someEventMethod() method as appropriate.
public class EventNotifier{
private SomeEvent se;
private boolean somethingHappened;
public EventNotifier (SomeEvent event){
//Save the event object for later use.
se = event;
// Nothing to report yet.
somethingHappened = false;
}
//...
public void doWork (){
//Check the predicate, which is set elsewhere.
if (somethingHappened){
//Signal the even by invoking the interface's method
se.someEventMethod();
}
//...
}
// ...
}
Finally, write some code that expects to receive the event notification, it must implement the SomeEvent interface and just pass a reference to itself to the event notifier, like this:
public class CallMe implements SomeEvent{
private EventNotifier en;
public CallMe (){
//Create the event notifier and pass itself to it.
en = new EventNotifier (this);
}
//Define the actual handler for the event
public void someEventMethod(){
// Some event interesting must have occurred
// Do something...
}
}
So, let's say I have 2 classes, Foo1 and Foo2, which is in a separate library.
Foo2 is a class that is already instantiated, and I cannot correctly reinstintate it as a subclass to override a method in Foo2.
Is there any way I can listen to a certain method that is called in Foo2, and then possibly cancel the execution of said method, and from there create another method. I understand if what I"m saying is confusing, hopefully I can get some help :).
class Foo{
void x(){
if (Foo2.x2().called){
//do stuff
}
}
}
class Foo2{
void x2(){
//Stuff done here...
}
}
Obviously, the above code won't do anything, it is just simple an example of what I am looking for.
you need a proxy on that object, and an interceptor on the method. There are a couple of ways to do it:
If you have an interface you can use reflection and proxies and invocation handlers docs.oracle.com/javase/6/docs/api/java/lang/reflect/Proxy.html.
If you have a concrete class you can use CGLIB cglib.sourceforge.net to create an enhancer for your class
If you are using Spring you can use the AOP http://static.springsource.org/spring/docs/2.5.5/reference/aop.html.
You can also use AspectJ http://www.eclipse.org/aspectj/doc/next/progguide/ to do the same
Cheers!
If you can't somehow subclass Foo2 or modify the existing lib (in worst case you could decompile/modify/recompile) you could use aspectj to intercept calls.
You'd probably want to use load-time weaving for this purpose. Check out the general documentation for load-time weaving here: http://www.eclipse.org/aspectj/doc/next/devguide/ltw.html. It's a fairly involved procedure to add/configure aspectj though so I'd only recommend it as a last resort
Depending on what you're trying to do, this might work:
If you had a boolean isX2Called in class Foo, when x2() is called, set isX2Called to true. Then in x(), you can check if isX2Called is true. If you ever want to reset, you can set isX2Called back to false. This might not work for all purposes though.
In my opinion, to solve this issue you could use a third class to act as a Decorator/Proxy.
For instance, you can do something like:
class FooManager {
private Foo1 f1;
private Foo2 f2;
private boolean canExecuteFooMethods(){
// Evaluate if should run any Foo1 or Foo2 method
}
public void foo1Method(){
if(canExecuteFooMethods()){
f1.x();
}
}
public void foo2Method(){
if(canExecuteFooMethods()){
f2.x();
}
}
}
Assuming that you can subclass the type, the following code would work perfectly:
Foo foo = new Foo() {
#Override
public void someMethod() {
super.someMethod();
//your logic here (listen, hook, spy, override, etc)
}
}
I have a generated object that I want to:
Preserve existing functionality of without injecting into the constructor and rewriting every method to call injectedObject.sameMethod().
Add additional functionality to that generated object without modifying the generated object.
add additional functionality to.
For example:
public class GeneratedObject {
public String getThis() { ... }
public String getThat() { ... }
}
public interface ObjectWrapper {
String doThisWithThat();
}
public class ObjectWrapperImpl extends GeneratedObject implements ObjectWrapper {
String doThisWithThat() { ... }
}
However, downcasting is not allowed, what is the proper implementation without rewriting a bunch of redundant code just to wrap the object?
I think decorator pattern may help you: "The decorator pattern can be used to extend (decorate) the functionality of a certain object at run-time, independently of other instances of the same class"
Have you tried aspectj? http://www.eclipse.org/aspectj/doc/next/progguide/semantics-declare.html It's a bit complicated but so is your request.
If you can extract an interface from GeneratedObject, then it would be possible to do this using a dynamic proxy. You would make a proxy which implemented the extracted interface and ObjectWrapper, with an invocation handler which passed all calls to methods in the GeneratedObject interface through to the delegate, and sent the doThisWithThat() calls elsewhere.
Proxies aren't pretty, but the ugliness is at least well-localised.