Напишите так называемый фабричный класс, который строит весь ваш проект за один шаг.
Пример:
// a class which store configuration parameters - must be instanstiable!
public class Configuration {
public Configuration() {
// get configuration from Properties file, Resource Bundle etc.
}
}
public class A {
private Configuration configuration;
public A(Configuration configuration) {
this.configuration = configuration;
}
}
public class B {
private Configuration configuration;
private A a;
public B(A a, Configuration configuration) {
this.a = a;
this.configuration = configuration;
}
}
public class C {
private Configuration configuration;
private B b;
public C(B b, Configuration configuration) {
this.b = b;
this.configuration = configuration;
}
}
Здесь у вас есть 3 класса и один класс конфигурации. Все они зависят от класса конфигурации, C зависит от B, а B зависит от A.
Как вы можете видеть, зависимости отражаются параметрами конструктора, что хорошо, потому что зависимости явные (это означает, что вы теперь, какие зависимости нужны, не слишком заглядывая в исходный код).
Но как вы строите этот граф объектов? Ну, используя фабричный класс (здесь это даже статическая фабрика):
public class ApplicationFactory {
// prevents instantiation
private ApplicationFactory() {};
public static C buildApplicationGraph() {
// first, build the leaf objects (objects without other dependencies), here
// Configuration
Configuration configuration = new Configuration();
// now, start injecting the dependencies needed
// a only need a Configuration object
A a = new A(configuration);
// B needs a Configuration and an A object
B b = new B(a, configuration);
// we're done here
return new C(b, configuration);
}
}
Как видите, вы строите граф объектов снизу вверх. Все зависимости являются явными, и вы отделяете процесс построения от бизнес-логики.
То, что мы здесь сделали, - это внедрение зависимостей в конструктор, то есть мы передали зависимости, в которых нуждается каждый класс, через конструктор. А для создания необходимых объектов мы написали фабрику.
В конце концов, у нас есть легкие классы (здесь нет строительных работ), явные зависимости (которых у вас нет синглтона) и максимальная гибкость (фабрика может даже вернуть подкласс C).
EDIT
Еще одним преимуществом является то, что вы можете тестировать свои классы изолированно, так как вы можете легко насмехаться над параметрами (например, передавая подклассы параметров).