"Inject" interface implementions into a class in java - java

I'm wrting something that look like this (of course its a bit more complex than this sample):
public class DoOnAll {
private List<IActionPerformer> actionPerformers;
public DoOnAll(List<IActionPerformer> actionPerformers) {
this.actionPerformers = actionPerformers;
}
public void callFromSomeWhere(String path) {
File f = new File(path);
List<File> list = Arrays.asList(f.listFiles());
for (File file : list) {
for (IActionPerformer action : actionPerformers) {
action.perform(file);
}
}
}
}
public interface IActionPerformer {
public void perform(File file);
}
public class SomePerformer implements IActionPerformer {
public void perform(File file) {
if (getFileType(file) = ".txt") {
doSomething
}
}
}
I have 2 questions:
Should I move the condition in SomePerformer to another method, boolean accept(File file) for example, and also add this method declartion to the interface?
If so, how would I "collect" all the accepted classes in DoOnAll? just go through the actionPerformers list and add all the accepeted to another list and then go through the list of accepted and .perform on them? Or is there another way usually used in the methodology?
Which ways are there for injecting the actionPerformrs list into the class?
I want to write independent implementations and define in a file, say xml file, which ones to inject into the list.

In answer to your second question, you should look into dependency injection. Java has a few good frameworks that can do this for you, for example:
Spring
Google Guice
Spring in particular allows you to define your application's components and dependencies in XML files. For examples see:
The IoC Container, in particular
Injecting Dependencies.
This last link has a subsection on constructor injection: creating java objects with dependencies supplied to their constructors, as your class DoOnAll requires.

WRT question 2: I agree with Dan, Spring or Guice.
WRT question 1: IMHO I would not create a conditional method as part of the interface. Either way you must call one method on each object, why call two? Let the object determine for itself if processing should be done. This also prevents any potential overhead in invoking multiple methods on the class. It also makes the calling method more straightforward.

Question 1. What you described is a chain-of-responsibility pattern. You can also check if a Performer can execute on file, of no - use next performer from a list. If no performes left - exception. You can use another method or make your perform method return true/false of throw exception if it can't perform.
Question 2. Use Spring in a simplest manner. Do it like:
ApplicationContext context = new ClassPathXmlApplicationContext("some_configuration.xml");
You can also try Google Guice.

General suggestions here:
Start simple (with what you have), and extend your interface when you have a use (case) for it. I'd just do if (accept(someFile)) perform(someFile); in an AbstractPerformer.performIfAccepted(File) method.
See other answers, I'm no expert in this area.

1) First off keep it simple... I think you need to decide what it is you want to do. Is it to (a) give a first responder the chance to respond to the presence of a file of a certain type, (b) allow all possible responders for that type to respond or (c) to identify a single specific responder to a file type.
If:
a) See Peter Gwiazda's answer (IMO).
b) Similar to (a) but permit multiple responders in the chain.
c) Where there is always a specific responder to a file type, you could use a factory to obtain a specific instance based on the file type. This hides the specifics of the implementation. There are disadvantages in an IoC environment but the factory can still be populated using IoC if required.
2) Check out "Inversion of Control" metaphor in general and Spring in particular (as already suggested).

Related

How to pass List<Object> objects to a constructor parameter (Object object1, Object object2)? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
My goal is to pass List<Object> objects to a constructor parameter Object object1, Object object2.
For example,
public class A {
public A(Object object1, Object object2) {
}
}
public class App {
public static void main(String[] args) {
List<Object> objects = new ArrayList<>();
objects.add(new Object());
objects.add(new Object())
A a = new A(...objects);
}
}
My expected result: It should work.
My actual result: The IDE throws error unexpected token.
Java, the language, has zero syntactical support for what you are trying to do here. And most likely never will, it is fundamentally tricky to do in java.
In general if you have a java method that takes a heap of arguments, all of which are of the same type, that's a badly designed method and you shouldn't be having it. Java could hypothetically grow a language feature that helps you out, but why cater to idiotic API designs, right?
Alternatively, you could have a List<Object> with a heterogenous (bunch of differently typed) objects, but you shouldn't have that either, it's un-java-like. Same cause for why java doesn't have this and probably never will: Why cater to bad code style?
Note that in java you can have 15 methods all with the same name differentiated solely by their types, so figuring out which one you actually intended to call is not necessarily simple.
You CAN do what you want with generics but it's a ton of code and very ugly:
public class Example {
public void callMe(String a, Integer b) {}
public void dynamicallyCallMe(List<Object> list) {
Method m = Example.class.getMethod("callMe", String.class, Integer.class);
m.invoke(this, list.toArray());
}
}
You do not want to this.
If you're facing a scenario where you do want this, then you'd want to change the environment some. For example, if these arguments are being provided by a user via a config script or whatnot, the method you are calling should be aware of this, and should therefore follow the interface public interface ConfigurableApp { void configure(List<String> aguments); } or whatnot. Make it explicit. Write a wrapper if you must, which would then be the place in your code where you perform any translations as needed.
If you're facing a more code-heavy config concept (where the config file needs to contain code, or code-esque constructions), then go all the way and make it a script file, run it with a script runner. Let them write that config file in javascript or what not and execute it from your java process.
And so on.
EDIT: With some more insights provided via the comments on this question:
What you're likely looking for is an SPI system that discovers factories.
SPI
SPI, or Service Provider Interface, is the name generally used in the java community for the idea of 'I have a mechanism by which a JDK can read a list of classes that implement some service straight from the classpath, usually via a file in META-INF/services/fully.qualified.name.ServiceInterface which lists 1 fully qualified classname per line. Reading these files out is baked into the core: ServiceLoader. Making them - lots of utilities around that let you just annotate a class and an annotation processor makes the services file for you.
The java module system has its own take on this idea, using the provides keyword. I suggest you don't mess with the java module system, though. Nobody* uses it.
Factories
The way ServiceLoader forces you to work, but this way is quite sensible so you should do this too (handrolling your own ServiceLoader is a single page class, so if you want to deviate, you can - it won't be difficult, it's just a bad idea stylewise), is that the involved classes have the following rules:
They MUST implement/extend the service interface.
They MUST have a public no-argument constructor.
The SPI system will then instantiate the class once using that constructor and will then give you a list of the service interface.
If this 'no arguments' thing is bothering you, that's when you add in a single layer of abstraction: The 'service' describes a factory, the classes in the META-INF/services class file are implementations of the factory service, and the factory's job is to make the instances you actually want.
Example
Let's say we are an image editor and you want a pluggable 'find interesting objects using AI'.
You start by making an interface that describes an image filter:
public interface ThingieFinder {
/** Describe what this thingiefinder finds */
String getDescription();
/** Try to find stuff within a segment of the image */
List<Thingie> find(Coords coords, double howSeriously);
}
But what's missing in this description is the constructor which would, of course, take the object representing the entire image.
Factories are the answer. Make this interface too:
public interface ThingieFinderFactory {
public ThingieFinder make(Image image);
}
This interface 'represents' the constructor. An implementation of this factory can be a trivial one-liner:
public class FaceFinderFactory implements ThingieFinderFactory {
public FaceFinder make(Image image) {
return new FaceFinder(image);
}
}
and this factory has a single no-args public constructor! ThingieFinderFactory can be the service, and this can be an implementation of it.
*) Rounding down considerably, but it's far less than half and that doesn't appear to be changing.
Mulitple problems in your code
List does not have put method. Learn about List from here
Java does not support spread operator(...) like JavaScript. In Java (...) is used for varargs
One of many ways to handle your errors.
public A(Object ... args) {
}
List<Object> objects = new ArrayList<>();
objects.add(new Object());
objects.add(new Object());
A a = new A(objects);

Extending functionality of Strategy pattern

I am developing an app that compares files. I decided to use the Strategy design pattern, to handle different formats, so I have something like this:
public class Report {
CompareStrategy strategy;
...
}
public interface CompareStrategy {
int compare(InputStream A, InputStreamB);
}
Then, naturally I implement the compare method for different file formats.
Now suppose I wanted to add another method, that deals with certain restrictions for the comparison (e.g. omit a row in case of an Excel or csv file, or omit a node in XML).
Would it be better to:
Add another method to the interface and every implementation (there are few for the moment)
Write a new interface which inherits from CompareStrategy and then implement it?
The second question is: since the differences can be of various types - would it be OK to make a marker interface Difference to enable something like:
int compareWithDifferences(..., Iterable<Difference> differences);
and then go on defining what a difference means for the specific file format?
Now suppose I wanted to add another method, that deals with certain restrictions for the comparison (e.g. omit a row in case of an Excel or csv file, or omit a node in XML).
Looks like you need the Template Pattern
You can create some abstract class like
public abstract class XMLCompareStrategy implements CompareStrategy {
public int compare(InputStream A, InputStreamB) {
// several steps
customMethod(...);
// more steps
}
protected abstract ... customMethod(...);
}
This way you can create several classes that have the main or core functionality and provide custom details for every situation
The answer really depends on your needs:
If the method will always be implemented - add it to the existing interface. If it's only optional - create a new interface that will extend the current one, and then the implemented class could implement either the base interface or the child interface if it needs both methods.
For your second question - looks a bit like over-designing to me, but again depends on your needs.
I think you should maybe write another interface that inherit from the CompareStrategy. Like that if you need to compareWithDifferences() you can, but you don't have to use this interface you still can use the simpler one with no differences.
As Jonathan said, if you can foresee difficulties prepare for it. In that case I think you should prepare. Indeed that won't cost you much time to create another interface and you won't have to refactor later.

Java - correct way to delegate methods

My program gets information from an external source (can be a file, a database, or anything else I might decide upon in the future).
I want to define an interface with all my data needs, and classes that implement it (e.g. a class to get the data from a file, another for DB, etc...).
I want the rest of my project to not care where the data comes from, and not need to create any object to get the data, for example to call "DataSource.getSomething();"
For that I need DataSource to contain a variable of the type of the interface and initialize it with one of the concrete implementations, and expose all of its methods (that come from the interface) as static methods.
So, lets say the interface name is K, and the concrete implementations are A,B,C.
The way I do it today is:
public class DataSource {
private static K myVar = new B();
// For **every** method in K I do something like this:
public static String getSomething() {
return myVar.doSomething();
}
...
}
This is very bad since I need to copy all the methods of the interface and make them static just so I can delegate it to myVar, and many other obvious reasons.
What is the correct way to do it? (maybe there is a design pattern for it?)
**Note - since this will be the backbone of many many other projects and I will use these calls from thousands (if not tens of thousands) code lines, I insist on keeping it simple like "DataSource.getSomething();", I do not want anything like "DataSource.getInstance().getSomething();" **
Edit :
I was offered here to use DI framework like Guice, does this mean I will need to add the DI code in every entry point (i.e. "main" method) in all my projects, or there is a way to do it once for all projects?
The classes using your data source should access it via an interface, and the correct instance provided to the class at construction time.
So first of all make DataSource an interface:
public interface DataSource {
String getSomething();
}
Now a concrete implementation:
public class B implements DataSource {
public String getSomething() {
//read a file, call a database whatever..
}
}
And then your calling class looks like this:
public class MyThingThatNeedsData {
private DataSource ds;
public MyThingThatNeedsData(DataSource ds) {
this.ds = ds;
}
public doSomethingRequiringData() {
String something = ds.getSomething();
//do whatever with the data
}
}
Somewhere else in your code you can instantiate this class:
public class Program {
public static void main(String[] args) {
DataSource ds = new B(); //Here we've picked the concrete implementation
MyThingThatNeedsData thing = new MyThingThatNeedsData(ds); //And we pass it in
String result = thing.doSomethingThatRequiresData();
}
}
You can do the last step using a Dependency Injection framework like Spring or Guice if you want to get fancy.
Bonus points: In your unit tests you can provide a mock/stub implementation of DataSource instead and your client class will be none the wiser!
I want to focus in my answer one important aspect in your question; you wrote:
Note - I insist on keeping it simple like "DataSource.getSomething();", I do not want anything like "DataSource.getInstance().getSomething();"
Thing is: simplicity is not measured on number of characters. Simplicity comes out of good design; and good design comes out of following best practices.
In other words: if you think that DataSource.getSomething() is "easier" than something that uses (for example) dependency injection to "magically" provide you with an object that implements a certain interfaces; then: you are mistaken!
It is the other way round: those are separated concerns: one the one hand; you should declare such an interface that describes the functionality that need. On the other hand, you have client code that needs an object of that interface. That is all you should be focusing on. The step of "creating" that object; and making it available to your code might look more complicated than just calling a static method; but I guarantee you: following the answer from Paolo will make your product better.
It is sometimes easy to do the wrong thing!
EDIT: one pattern that I am using:
interface SomeFunc {
void foo();
}
class SomeFuncImpl implements SomeFunc {
...
}
enum SomeFuncProvider implements SomeFunc {
INSTANCE;
private final SomeFunc delegatee = new SomeFuncImpl();
#Override
void foo() { delegatee.foo(); }
This pattern allows you to write client code like
class Client {
private final SomeFunc func;
Client() { this(SomeFuncProvider.INSTANCE); }
Client(SomeFunc func) { this.func = func; }
Meaning:
There is a nice (singleton-correctway) of accessing an object giving you your functionality
The impl class is completely unit-testable
Client code uses dependency injection, and is therefore also fully unit-testable
My program gets information from an external source (can be a file, a database, or anything else I might decide upon in the future).
This is the thought behind patterns such as Data Access Object (short DAO) or the Repository pattern. The difference is blurry. Both are about abstracting away a data source behind a uniform interface. A common approach is having one DAO/Repository class per business- or database entity. It's up to you if you want them all to behave similarly (e.g. CRUD methods) or be specific with special queries and stuff. In Java EE the patterns are most often implemented using the Java Persistence API (short JPA).
For that I need DataSource to contain a variable of the type of the
interface and initialize it with one of the concrete implementations,
For this initialization you don't want to know or define the type in the using classes. This is where Inversion Of Control (short IOC) comes into play. A simple way to archieve this is putting all dependencies into constructor parameters, but this way you only move the problem one stage up. In Java context you'll often hear the term Context and Dependency Injection (short CDI) which is basically an implementation of the IOC idea. Specifically in Java EE there's the CDI package, which enables you to inject instances of classes based on their implemented interfaces. You basically do not call any constructors anymore when using CDI effectively. You only define your class' dependencies using annotations.
and expose all of its methods (that come from the interface)
This is a misconception. You do want it to expose the interface-defined method ONLY. All other public methods on the class are irrelevant and only meant for testing or in rare cases where you want to use specific behavior.
as static methods.
Having stateful classes with static method only is an antipattern. Since your data source classes must contain a reference to the underlying data source, they have a state. That said, the class needs a private field. This makes usage through static methods impossible. Additionally, static classes are very hard to test and do not behave nicely in multi-threaded environments.

Framework to populate common field in unrelated classes

I'm attempting to write a framework to handle an interface with an external library and its API. As part of that, I need to populate a header field that exists with the same name and type in each of many (70ish) possible message classes. Unfortunately, instead of having each message class derive from a common base class that would contain the header field, each one is entirely separate.
As as toy example:
public class A
{
public Header header;
public Integer aData;
}
public class B
{
public Header header;
public Long bData;
}
If they had designed them sanely where A and B derived from some base class containing the header, I could just do:
public boolean sendMessage(BaseType b)
{
b.header = populateHeader();
stuffNecessaryToSendMessage();
}
But as it stands, Object is the only common class. The various options I've thought of would be:
A separate method for each type. This would work, and be fast, but the code duplication would be depressingly wasteful.
I could subclass each of the types and have them implement a common Interface. While this would work, creating 70+ subclasses and then modifying the code to use them instead of the original messaging classes is a bridge too far.
Reflection. Workable, but I'd expect it to be too slow (performance is a concern here)
Given these, the separate method for each seems like my best bet, but I'd love to have a better option.
I'd suggest you the following. Create a set of interfaces you'd like to have. For example
public interface HeaderHolder {
public void setHeader(Header header);
public Header getHeader();
}
I'd like your classes to implement them, i.e you's like that your class B is defined as
class B implements HeaderHolder {...}
Unfortunately it is not. Now problem!
Create facade:
public class InterfaceWrapper {
public <T> T wrap(Object obj, Class<T> api) {...}
}
You can implement it at this phase using dynamic proxy. Yes, dynamic proxy uses reflection, but forget about this right now.
Once you are done you can use your InterfaceWrapper as following:
B b = new B();
new IntefaceWrapper().wrap(b, HeaderHolder.class).setHeader("my header");
As you can see now you can set headers to any class you want (if it has appropriate property). Once you are done you can check your performance. If and only if usage of reflection in dynamic proxy is a bottleneck change the implementation to code generation (e.g. based on custom annotation, package name etc). There are a lot of tools that can help you to do this or alternatively you can implement such logic yourself. The point is that you can always change implementation of IntefaceWrapper without changing other code.
But avoid premature optimization. Reflection works very efficiently these days. Sun/Oracle worked hard to achieve this. They for example create classes on the fly and cache them to make reflection faster. So probably taking in consideration the full flow the reflective call does not take too much time.
How about dynamically generating those 70+ subclasses in the build time of your project ? That way you won't need to maintain 70+ source files while keeping the benefits of the approach from your second bullet.
The only library I know of that can do this Dozer. It does use reflection, but the good news is that it'll be easier to test if it's slow than to write your own reflection code to discover that it's slow.
By default, dozer will call the same getter/setters on two objects even if they are completely different. You can configure it in much more complex ways though. For example, you can also tell it to access the fields directly. You can give it a custom converter to convert a Map to a List, things like that.
You can just take one populated instance, or perhaps even your own BaseType and say, dozer.map(baseType, SubType.class);

How do I intercept a method invocation with standard java features (no AspectJ etc)?

I want to intercept all method invocations to some class MyClass to be able to react on some setter-invocations.
I tried to use dynamic proxies, but as far as I know, this only works for classes implementing some interface. But MyClass does not have such an interface.
Is there any other way, besides implementing a wrapper class, that delegates all invocations to a member, which is an instance of the MyClass or besided using AOP?
As you note, you cannot use JDK dynamic proxies (no interface), but using Spring and CGLIB (JAR included with Spring), you can do the following:
public class Foo
{
public void setBar()
{
throw new UnsupportedOperationException("should not go here");
}
public void redirected()
{
System.out.println("Yiha");
}
}
Foo foo = new Foo();
ProxyFactory pf = new ProxyFactory(foo);
pf.addAdvice(new MethodInterceptor()
{
public Object invoke(MethodInvocation mi) throws Throwable
{
if (mi.getMethod().getName().startsWith("set"))
{
Method redirect = mi.getThis().getClass().getMethod("redirected");
redirect.invoke(mi.getThis());
}
return null;
}
});
Foo proxy = (Foo) pf.getProxy();
proxy.setBar(); // prints "Yiha"
If you are prepared to do something really ugly, have a look at:
http://docs.oracle.com/javase/7/docs/technotes/guides/jpda/
Basically the debugger interface ought to allow you to attach like a debugger, and hence intercept calls. Bear in mind I think this is a really bad idea, but you asked if it was possible.
Java doesn't have any actual language features for method interception (not sure any static language does)
I kinda like Nick's idea of using the debugger interface, that's just mean.
I think the short answer you need is: No there isn't a way of intercepting a method call in Java without actually replacing the class using a proxy or wrapper.
Note: The AOP libraries just make this happen automatically.
Some of the Java gurus might frown upon this but I've had some good success with avoiding primitive types and setters altogether. My class looks like this:
class Employee extends SmartPojo {
public SmartString name;
public SmartInt age;
}
You'll notice two things: 1. everything is public. 2. No constructor.
The magic happens in SmartPojo which searches for any field which implements the "Smart" interface and initializes it. Since this is no primitive (and no final class), I can add set() and get() methods for all fields anywhere in my model in a single place. So no setter/getter wastes anymore, it's stunningly simple to add notification (also in a single place), etc.
True, this is no POJO anymore and it's not a Bean in most ways but I've found that these old ideas limit me more than they help. YMMV.
I just developed a small framework for this purpose.
You can check it out at: http://code.google.com/p/java-interceptor/ (use svn to check out).
There isn't a lot of magic in AspectJ. You can write your own agent. http://java.sun.com/javase/6/docs/api/java/lang/instrument/package-summary.html seems to be good starting point.
Why cannot your class implement an interface? You could just extract some interface from it containing all the methods that you want to intercept and use the dynamic proxies mechanism easily. It's also a good programming practice to code with interfaces and not classes.
You could use Spring framework with Spring AOP capabilities (which are using dynamic proxies inside) to do it. You will just have to define your class as a Spring bean in the configuration file and clients of your class will have to either get its instance from the Spring application context or as a dependency automatically (by defining the setMyClass(MyClass mc) method for instance). From there you can easily go to defining an aspect that intercepts all the method calls to this class.

Categories

Resources