aspose file tools*
The moose likes Java in General and the fly likes Keeping a list of all instances implementing an interface. Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "Keeping a list of all instances implementing an interface." Watch "Keeping a list of all instances implementing an interface." New topic
Author

Keeping a list of all instances implementing an interface.

Daniel Larsson
Greenhorn

Joined: Nov 12, 2012
Posts: 9

I did a quick search and found no other queries about this, might be because I don't really know what keywords would be applicable than the ones I use here.

Scenario: I want to have a list that includes every instance ever made of a certain interface.

All implementers of this interface will be singletons, they will be static and immutable and the instance is only used for reference.

I want to avoid having to manually add each instance to the list to keep track of all these singletons, I want the mere act of writing another implementing singleton class to make it written in the list.

A method to get all instances and put them in a list is ok too, the issue is that I want to be able to implement the interface without having to write it into the list manually somewhere outside the class to ensure its in the list.

The problem is that its a catch 22 for me, to make sure that these classes have written themselves into the list I have to make sure they are loaded, and I got the impression that classes statical initialisers are loaded when the class is demanded the first time?

Performance is not an issue, it will only happen at the startup of the application and this master list is used to sort the instances into other lists depending on their properties.

Thanks in advance.
Pat Farrell
Rancher

Joined: Aug 11, 2007
Posts: 4659
    
    5

I'm not sure that what you say you want to do is really a good idea. But ignoring that, this is what I'd do.

I'd define the interface Foo and an AbstractFoo class that has a constructor that adds "this" to the list.
Each class that implements the Foo interface then just has to subclass from AbstractFoo and call the constructor.
The compiler will do the right thing, as long as the developer doesn't deliberately screw things up.

But I still think this is probably a really bad idea.

Jayesh A Lalwani
Bartender

Joined: Jan 17, 2008
Posts: 2431
    
  28

Keeping track of every instance of a particular class is easy if you can change the class. You can change the constructor to make it add this to a singleton list. Or as Pat said, put this functionality in a base class and then have all your classes extend that base class

Changing non-singleton objects to singleton objects is impossible to do unless you have used some sort of Creation pattern. If you had factory classes, you could easily control the factory to return the singleton. If you are using DI, you can easily change your DI framework to create only one instance. However, if you have new XXXX() calls everywhere, there's no way you can change the behavior of new to return the same instance everytime.

However, let's assume you did figure out a way of changing non-singletons to singletons, you might still have a problem. Singletons either have to be stateless or immutable, otherwise you might run into a problem that state from one thread is being shared with another thread, or state from one call is bleeding into a consecutive call. Now, it's not enough for the Singleton to have an immutable interface (like a interface with only get methods.. no set methods), they have to be immutable. If you aren't sure that all your classes are immutable, you might run into a problem.
Daniel Larsson
Greenhorn

Joined: Nov 12, 2012
Posts: 9

Pat Farrell wrote:I'm not sure that what you say you want to do is really a good idea. But ignoring that, this is what I'd do.

I'd define the interface Foo and an AbstractFoo class that has a constructor that adds "this" to the list.
Each class that implements the Foo interface then just has to subclass from AbstractFoo and call the constructor.
The compiler will do the right thing, as long as the developer doesn't deliberately screw things up.

But I still think this is probably a really bad idea.



I'm not certain its a good idea either, but I think it will work.

Anyway this is a good idea, but I have already thought about it. The issue with this solution is: when and where does the class get instantiated? It has to be called from the outside which sort of means there has to be an argument excecuted outside of the subclass. Which essentially means there already exists a handmade list, and I want it automated. I read up on javas static initialisation orders and my anticipation is correct, if I use static initialisation only the classes that has been accessed will be initialised, so whatever happens I see no solution except accessing the classes from outside the class definition.

EDIT: I just realised I never actually said I wanted the classes to initialise them selves. I'm sorry for being unclear. The more I think about this the less I think it will be possible to do. My motive for this, is that the future implementer of the interface in question should not have to go in and manually add the new class to a list, but only need to write the class, compile it, and put it in the same folder as the others and it would be included. Or if that doesn't work, supply me with the file and I'll do it when recompiling the entire application.
Manuel Petermann
Ranch Hand

Joined: Jul 19, 2011
Posts: 175

I would question the design decision that you have to add every implementation to a list in the first place. Take a step back and have a look if you can get around that.


Please correct my English.
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 8186
    
  23

Daniel Larsson wrote:EDIT: I just realised I never actually said I wanted the classes to initialise them selves. ...

Hunh? This seems to be getting more and more bizarre.

Quite apart from wondering why you would want to do this, or even the wisdom of having singletons to start with, I agree with Manuel:
back up and explain to us what you're trying to do, not how you want to do it.

Winston

Isn't it funny how there's always time and money enough to do it WRONG?
Articles by Winston can be found here
Daniel Larsson
Greenhorn

Joined: Nov 12, 2012
Posts: 9

Winston Gutkowski wrote:
Daniel Larsson wrote:EDIT: I just realised I never actually said I wanted the classes to initialise them selves. ...

Hunh? This seems to be getting more and more bizarre.

Quite apart from wondering why you would want to do this, or even the wisdom of having singletons to start with, I agree with Manuel:
back up and explain to us what you're trying to do, not how you want to do it.

Winston


Well I can't blame you, I'm not sure it follow any standard patterns but I find it fitting so far to my purpose and logic, I'm self taught so some eccentricities are to be expected I suppose ;). So why singletons? Because I need the reference to the class, as it will be used in lists. The singletons are stateless actually, they implement an interface and that's it, no real reason to keep them bound to a single instance, but no reason not to either. The reason I want them in a list is that the application will ask another class that manages these classes and produces lists of them(This might be what is called factory methods?). The parameters for retrieving a list of these classes is a list of properties, and the properties of each implementation is retrieved in a method in each implementing class. Thus I want a kind of masterlist of every applicable instance so I can loop through it and select the implementations that have the correct configuration of properties.

I plan to let the application use this list to produce a new list for every possible configuration and be able to retrieve them without creating new lists. There aren't THAT many configurations that will happen so its a marginal expense to have them all in memory instead of making new ones quite often and inducing unnecessary GC(its a lag sensitive application), and also hopefully speeding up the retrieval.

All of this nonsense is because I want to have all the code when implementing new classes for the interface inside the one file, making it easier to plugin new ones and remove old ones without having to remember to clear a manual list somewhere. Over the top? Perhaps. But its a good learning experience! =)

I think I have found a solution, using the classpath I can list all the classfiles in the package that contain these implementations, and thus create instances trough reflection by using the string. This makes me wonder though, what happens with portability of my app when I use that kind of reflection? Anything I should be mindful of? Also can I compile new classes by themselves and just put them in the correct package folder and expect them to be used appropriately?
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 8186
    
  23

Daniel Larsson wrote:So why singletons? Because I need the reference to the class, as it will be used in lists. The singletons are stateless actually, they implement an interface and that's it, no real reason to keep them bound to a single instance, but no reason not to either.

OK, so presumably each one is just a different implementation of the interface. Assuming that anyone can create them (and if I ever planned on doing something like this, I'd probably go with Pat's suggestion) how do you stop people 're-inventing the wheel'? - ie, creating a new class with the same implementation as an existing one. In fact, since you say the class is stateless, what would distinguish one implementation from another in the first place?

The reason I want them in a list is that the application will ask another class that manages these classes and produces lists of them(This might be what is called factory methods?).

Not really. Sounds more like some sort of selector.

Thus I want a kind of masterlist of every applicable instance so I can loop through it and select the implementations that have the correct configuration of properties.

And here's where you lose me. If the class is stateless, how on earth can it have properties?

so its a marginal expense to have them all in memory instead of making new ones quite often and inducing unnecessary GC(its a lag sensitive application), and also hopefully speeding up the retrieval.

As far as I know, classes aren't GC'd (although I'm no Java memory expert), and I suspect that if they are, there'll be a darn good reason why; so interfering with that process is likely to be asking for trouble.

what happens with portability of my app when I use that kind of reflection? Anything I should be mindful of? Also can I compile new classes by themselves and just put them in the correct package folder and expect them to be used appropriately?

Well, you're probably asking the wrong person here because I have an inbuilt antipathy to reflection:
It's complex, it's error-prone, and it's SLOW; and compiling on the fly just adds a whole new layer to that complexity. I'd also say that Java is probably not the right language for this kind of requirement.

From what you describe, I'm also wondering if you're not looking for some sort of dependency injection mechanism. If so, there are plenty around already; of which the best-known one I know of is Guice.

It sounds to me like you're overthinking this on a grand scale.

Winston
Jayesh A Lalwani
Bartender

Joined: Jan 17, 2008
Posts: 2431
    
  28

Do your implementation classes self-declare what combination of properties they work on? Like could you give the list of all properties to each and every implementation of the interface, and will they be able to determine whether they should execute or not? If yes, I would use Chain Of Responsibility coupled with a rudimentary IoC pattern.

Let me explain

What I would do is define my interface like this



Then in my class that manages the instances, I would add a method that finds all the Doers that match the properties



Your caller can call all the returned doers.

Now, to your original question.. how do you create all objects that implement the interface and put them in the list. Classpath scanning will work, but remember that classpath scanning is very very costly. The way I would do this is this:- Introduce a compile time annotation, and write a compile time annotation processor that will create a file that contains a list of classes that implement the interface. This file should be bundled in with the application, Your DoerLocator (or DoerFactory whatever you want to call it) can read the file and use reflection to create instances of the classes at startup. This way you are essentially "classpath scanning" during compile time.

Like Ulf said, reflection is costly, but if you do the reflection only on load time, then you are incurring the cost only at load time, which will be ok for most applications. Since, all your clients are coded to the interface, calls to your methods shouldn't incur any reflection.
Daniel Larsson
Greenhorn

Joined: Nov 12, 2012
Posts: 9

I solved it by using the path to the package, iterating trough the classes and by reflection, invoking a no args method called initialize. This method creates an instance and adds it to the list.
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: Keeping a list of all instances implementing an interface.