Instead of scattering implementation details throughout your application, you should use IoC (Inversion of Control) to specify your concrete classes at startup in a centralized way. As you can see below, MentaContainer supports IoC in a variety of ways.
IoC:
public interface Logger { // contract methods } public class FileLogger implements Logger { // methods implementation } // inversion of control: Container c = new MentaContainer(); // starting up the container c.ioc(Logger.class, FileLogger.class); // choosing an implementation Logger logger = c.get(Logger.class); // requesting an instance
Specifying constructor parameters:
public class FileLogger implements Logger { private final String filename; public FileLogger(String filename) { this.filename = filename; } // methods implementation } // inversion of control: Container c = new MentaContainer(); c.ioc(Logger.class, FileLogger.class).addInitValue("/var/log/stdout.log"); Logger logger = c.get(Logger.class);
Specifying a property:
public class FileLogger implements Logger { private int maxSize = 1024; public void setMaxSize(int maxSize) { this.maxSize = maxSize; } // methods implementation } // inversion of control: Container c = new MentaContainer(); c.ioc(Logger.class, FileLogger.class).addPropertyValue(2048); Logger logger = c.get(Logger.class);