4

I will directly come to our current working flow so that you can understand the problem in a clear picture.

I am attached in Laboratory Automation System in which Analyzer (a machine that performs medical tests) sends data to Host (our Automation System). Every analyzer is assigned a unique ID (Machine ID) and is saved in Database with its relevant controller's complete path. A controller is simple Java class that keeps the connection between Analyzer and Host.

Now that controller (a java class) is instantiated at run-time when user turns on our software. User provides machine id and based on that machine id, its relevant controller is instantiated. The Controller is instantiated using Reflections which is the PROBLEM here. We are looking for a solution to avoid using Reflection.

Adding to the complexity, we have multiple Analyzers of same types, which means we will have same Controller for every Analyzer of same type. In other words, If we have 5 same Analyzers, our program will use Reflections to create its instance.

I hope I made my point clear, What approach is best alternate of Reflections? Please note that I know Design Patterns and all stuff but probably none of that solved my problem and we are still relying on Reflections.

Thanks, let me know if further information is required.

  • 5
    Could you elaborate on what actually the problem is with it? Why is it a problem? And how are you using Reflection exactly? I'm guessing that you would have a list of possible controllers somewhere (probably based on an interface) and then examine them to see it they can handle a specific machine id? – Quido Sep 5 '18 at 9:27
  • 4
    Creating an instance of a class given its name is unavoidable if you aren't willing to hardcode it in your program. It is considered to be more flexible this way. Why do you need to remove it? The alternative being a gigantic enum or table which directly associates an id to its handler class. – Neil Sep 5 '18 at 9:30
  • 3
    First ask yourself what your problem is with reflection. Java is built on reflection.. it's a fundamental part of the language. It's just code like all your other code. If it is just that your security team doesn't like it.. get them to say why.. Other than that you'll need to maintain a mapping of classes to names. Perhaps using an Enum. See factory method answer below also. But don't change your code for no good reason. – Richard Sep 5 '18 at 11:00
  • 1
    @Neil You got it right. I think I should stick with Reflection. This is the only possible solution for this scenario. – Faizan Mubasher Sep 5 '18 at 13:02
  • @FaizanMubasher I think it's important to distinguish between using reflection to instantiate a class and using reflection unnecessarily. You should avoid reflection if you're using it to write "clever code". Don't write clever code, though reflection is still sometimes necessary under such circumstances. – Neil Sep 5 '18 at 13:10
2

Use the Factory Pattern

class ControllerFacatory 
{
    private Dictionary<string,string> ControlerTypeLookup
    public Controller Get(string machineId)
    {
         if(ControlerTypeLookup[machineId] == "SuperAnalyser")
         {
             return new SuperAnalyser();
         }...
    }
}

Also if you already have a DI framework you can do things like

container.RegisterType<Controller, SuperAnalyser>("SuperAnalyser");
container.Resolve<Controller>("SuperAnalyser");

which essentially does the same thing.

I'm not clear on whether using the same controller from multiple machines is desired behaviour or not? either way you can adjust the behaviour, either directly caching the Controller in the factory, or through the options your DI container of choice offers you.

  • same controller from multiple machines is desired behaviour or not, I think I am unable to make it clear. By same controller I mean same Java class for every Analyzer. I don't need to write new Java class for multiple Analyzers of same type. – Faizan Mubasher Sep 5 '18 at 12:58
  • 1
    Factory Pattern cannot be used in this scenario. As Neil commented, if I am not willing to hard code, I will end up gigantic enum. – Faizan Mubasher Sep 5 '18 at 13:03
  • hmm. What exactly is the requirement which makes a big enum bad? Is it ok to use reflection a single time on application start? Is it ok to use code generation templates to generate the factory class? – Ewan Sep 5 '18 at 13:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.