Search code examples
javaabstract-factory

AbstractFactory with a twist


I am stuck with a programming problem:

I have two Java projects, in my Eclipse IDE: ProjectA, and ProjectB. ProjectB references ProjectA

I have declared a class in ProjectA: ClassA, and one in ProjectB: ClassB, such that:

public class ClassA{
  public static Object foo(){
   //blah
  }
}

public class ClassB extends ClassA{
  public static Object foo(){
    //blah
  }
}

I also have a class called ClientClass, in ProjectA. This ClientClass earlier used to create an instance of ClassA and use it. But now, based on an environment setting, the ClientClass should be provided the option to use ClassA or ClassB.

This seemed to be a problem for the AbstractFactory pattern, or so I thought. I need to create a Factory that provides access to ClassA or ClassB. ClientClass should not be aware that it is ClassA or ClassB. This requires me to create an interface for ClassA and ClassB.

Issues I ran into:

  • ClientClass cannot refer to ClassB directly (no import statements / or new invocation), because ClassB is in a different project. This may be an Eclipse IDE restriction, but it also makes sense to me when viewing these two projects as jar files. A cyclic relationship is avoidable.
  • I cannot create a Factory interface and a common interface for ClassA & ClassB, and then via the AbstractFactory pattern provide a ClassAFactory or a ClassBFactory. This is because the methods to be invoked on ClassA and ClassB are static ones. The methods on these classes would need to be present on the interface. But then, in Java, one can't have an "abstract static" modifier

Can anyone suggest an elegant solution for this problem?


Solution

  • Well, there are a number of problems here. For starters, and this is the biggest one, this isn't going to work because you can't override static methods in Java. The goal, I think, of what you're saying is to be able to substitute, at run time, ClassA for ClassB or B or A or whatever, depending on some parameters. In order to do that, you need to be able to take advantage of dynamic dispatch (or, simply put, virtual methods) that would allow the runtime system to select the memory address of the method to be executed at run time. This isn't possible with static methods. You need to make the methods nonstatic for this to work. You don't have to specifically design a Java Interface but when you extend ClassA with ClassB, you'll be able to treat your objects as if they are simply a ClassA object.

    All of that said, if you remove the static modifiers from the methods and make them nonstatic, then you could use ClassB in project A without having any import statements what-so-ever in the client class you're talking about. However, somewhere in project A, somebody is going to need to be aware of ClassB in order to instantiate it. That is, of course, unless you want to do some runtime binding stuff and load the class dynamically using a string. Does that make sense?