Когда мне нужен неизменный объект (все члены являются окончательными), который принимает в конструкторе много разных параметров, я обычно использую шаблон Builder.
В этом случае вы можете сделать строителей подклассами друг друга, и таким образом вы все равно сохраните способность расширяться.
В качестве примера вы можете увидеть API Guava для ImmutableCollection Builder .
Или, если вам не требуется неизменяемость, вот пример CacheBuilder , также взятый из той же библиотеки:
Cache<Key, Graph> graphs = CacheBuilder.newBuilder()
.concurrencyLevel(4)
.weakKeys()
.maximumSize(10000)
.expireAfterWrite(10, TimeUnit.MINUTES)
.build(
new CacheLoader<Key, Graph>() {
public Graph load(Key key) throws AnyException {
return createExpensiveGraph(key);
}
});
Как вы можете видеть, использование компоновщика заменяет необходимость передачи 6 параметров в конструкторе и делает код более читабельным / пригодным для использования.
Если вы все еще не хотите использовать компоновщики, я бы выбрал вариант (3), поскольку это предотвратит некоторые хлопоты, связанные с поддержкой очень длинного конструктора