3

TL;DR: How can I use composition a Builder Pattern with Spring IoC?

I am creating a Spring project that populates a table based on distribution parameters for some fields (i.e. 50% of records must be of type A, 40% of type B, 10% of type C; For each type 50% must be of subtype 1, 20% of subtype 2, 10% of subtype 3, etc etc).

In order to speed up record creation I have a RecordFactory that calculates the distribution for these parameters and returns a list of RecordBuilder. Each RecordBuilder extends the Callable interface to process and return records concurrently:

ActivityDiagram

What I did so far, considering just type A, B and C was to create a TypeABuilder, TypeBBuilder and TypeCBuilder which returned different ProcessorFactory implementations for each type:

public class RecordFactory {
    @Inject
    private transient TypeABuilder aBuilder;
    @Inject
    private transient TypeBBuilder bBuilder;
    @Inject
    private transient TypeCBuilder cBuilder;

    public List<DataBuilder> getBuilders() {
        // calculates distribution for each type and add the builders accordingly
    }
}

But, obviously, this is a bad design. As the project becomes more complex, I'd need to have m x n classes for each possible combination.

A better design would be to use composition, create DataBuilders according to the parameters needed. How can I do this without losing the benefits o Spring IoC?


Update:

I have changed the way the RecordFactory builds ProcessorFactory. Instead of separate Builder objects, I have one Builder object which uses the Builder pattern to create a ProcessorFactory based on my needs:

@Component
@Scope("prototype")
public class Builder {
    private Type type;
    private Subtype subtype;

    public Builder setType(Type type) {`
        this.type = type;
        return this;
    }

    public setSubtype(Subtype subtype) {
        this.subtype = subtype;
        return this;
    }

    public ProcessorFactory createFactory() {
        return new ProcessorFactoryImpl(this);
    }
}

public class ProcessorFactoryImpl {
    @Inject
    private transient TypeProcessor typeProcessor;

    @Inject
    private transient SubtypeProcessor subtypeProcessor;

    public ProcessorFactoryImpl(Builder builder) {
        typeProcessor.setType(builder.getType());
        processors.add(typeProcessor);
        subtypeProcessor.setSubtype(builder.getSubtype());
        processors.add(subTypeProcessor);
    }
}

Now my problem is: when I create a new ProcessorFactoryImpl in my Builder, I cannot inject my processors. How can I use the builder pattern with Spring, maintaining that kind of flexibility?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Tarek
  • 3,080
  • 5
  • 38
  • 54
  • Have you thought about AbstractFactory by Spring? I don't understand very well your scenario, but the better way is to use an AbstractFactory. – Xstian Nov 05 '14 at 13:11
  • @Xstian right, but wouldn't I still need m x n factory implementations to create DataBuilders? – Tarek Nov 05 '14 at 13:31
  • You must have all implementation anyway , but you could use it by `lookup-method` and AbstractFactory, in order to don't lose spring benefits. – Xstian Nov 05 '14 at 13:37

0 Answers0