Design Pattern Questions

I have the following problem that I want to solve ellegantly:

public interface IMyclass { } public class A { public void Init(IMyclass class){?} public IMyclass CreateMyClass(){?} } 

At the beginning of the system, I want to define a dynamic IMyClass type using Init (), and during system startup I would like to create new instances of type I, defined in init.

Notes:
1. IMyclass should be an interface
2. Dynamic type IMyclass, known only at init (I do not have a constructor after :))
3. I could do this using the reflection cloning method or determining in IMyclass, are there any better solutions?

Thanks.

+4
source share
4 answers

You can pass the provider to class A

 public class A { IMyClassProvider _provider; public void Init(IMyClassProvider provider) { _provider = provider; } public IMyclass CreateMyClass() { return _provider.Create(); } } 

Or maybe with a delegate constructor

 public class A { Func<IMyclass> _ctor; public void Init(Func<IMyclass> ctor) { _ctor = ctor; } public IMyclass CreateMyClass() { return _ctor(); } } 

Note that both of these examples will explode if Init not called before CreateMyClass , you will need some checking, or better, your init will execute in the constructor.

Did I understand the question correctly?

+2
source

This is a kind of dependency injection , you should read:

Basically, you have a class A that is populated by factories (or suppliers) during initialization. Then you use A instead of calling new .

Quick example:

 interface Provider<V> { V instance(Object... args); } class Dispatch { // you can make a singleton out of this class Map<Class, Provider> map; <T> void register(Class<T> cl, Provider<? extends T> p) { // you can also bind to superclasses of cl map.put(cl, p); } <T, I extends T> void register(Class<T> cl, final Class<I> impl) { register(cl, new Provider<I>() { I instance(Object... args) { // this class should be refactored and put in a separate file // a constructor with arguments could be found based on types of args values // moreover, exceptions should be handled return impl.newInstace(); } }); } <T> T instance(Class<T> cl, Object... args) { return map.get(cl).instance(args); } } // usage interface MyIf { ... } class MyIfImpl implements MyIf { ... } Dispatch d = new Dispatch(); d.register(MyIf.class, new Provider<MyIf>() { MyIf instance(Object... args) { return new MyIfImpl(); } }); // or just d.register(MyIf.class, MyIfImpl.class); MyIf i = d.instance(MyIf.class); 

Edit: added register(Class, Class)

+2
source

If you just want to create an instance of one class in CreateMyClass() without additional configuration, you can use reflection.

 public class A { private Class prototype; public void Init(IMyClass object) { this.prototype = object.getClass(); } public IMyClass CreateMyClass() { return prototype.newInstance(); } } 

I suspect you want more than that, and if you need to explain how you want to use it. You may be looking for Builder or Factory templates.

+1
source

You will need Reflection at some point due to visibility. If you can take Reflection once in advance and not use it again, that would probably be ideal, right?

You can put the getInstance() method on a hidden interface (located in the same package as IMyClass , MyClassImpl and A , but not ClientOfA ), and then pass the prototype MyClassImpl to A.init() .

 // -- You wish you would have thought of the word prototypeable! ...maybe? interface IMyClassPrototypeable extends IMyClass { public IMyClass getInstance(); } class MyClassImpl implements IMyClassPrototypeable // -- and IMyClass by extension. { // -- Still not visible outside this package. public IMyClass getInstance() { return new MyClassImpl(); } } class A { private IMyClassPrototypeable prototype; // -- This method is package-private. void init( IMyClassPrototypeable prototype ) { this.prototype = prototype; } public IMyClass createMyClass() { return prototype.getInstance(); } } 

This solution would require Reflection to create an instance of the MyClassImpl prototype that could be executed using Spring (or some other form of dependency injection). It uses the Prototype pattern, the Factory -method pattern, and easily supports the Singleton / Pool pattern, but remember that more design patterns used are not always better. In fact, this can make design (and code) more complex and difficult for beginners to understand.

For the record, the only reason I would even think of this solution is because it takes a hit of reflection once, in front, and not every time createMyClass() is createMyClass() , on which the original poster indicated that he / she will be often.

+1
source

All Articles