J L
J L

Reputation: 987

Builder with generics

I have the following hierarchy

A doubly generic class named

public class Service<T, U> 
{
    private final Supplier<T>
    private final Function<T, U>
    private final Consumer<U>
    // more fields and methods ...
}

A Builder for that class ServiceBuilder<T, U> with the usual fluent API for builder

public class ServiceBuilder<T, U>
{
    private Supplier<T> supplier;
    private Function<T, U> mapper;
    private Consumer<U> consumer;
    // more fields and methods ....

    public ServiceBuilder<T, U> withSupplier(Supplier<T> supplier)
    {
        this.supplier = supplier;
        return this;
    }

    // more fields and methods ....

    public Service<T, U> build()
    {
        return new Service(supplier, mapper, consumer);
    }
}

Based on this, I want to provide an easy to use Supplier of T, let's say DummySupplier

public class DummySupplier implements Supplier<SomeObject>
{
    public SomeObject get()
    {
        return new SomeObject();
    }
}

And I want a ServiceBuilder<SomeObject, T> that makes use of this supplier, effectively fixing T so that I only need a Function<SomeObject, U> mapper and a Consumer<U> consumer> to build my service.

How may I approach this? Extending ServiceBuilder does not work because all its existing methods that I want to reuse return ServiceBuilder and not some class extending ServiceBuilder ...

Is there some known pattern to approach?

Upvotes: 1

Views: 169

Answers (2)

daniu
daniu

Reputation: 15028

I don't see why you need a specified subclass, you can just create a factory method giving you a standard ServiceBuilder<SomeClass, U>.

public static <U> ServiceBuilder<SomeClass, U> withDummyBuilder() {
    return new ServiceBuilder<SomeClass, U>().withSupplier(SomeClass::new);
}

You can then call withSupplier again and override the new SomeClass() supplier, but I don't see why that's a problem.

Upvotes: 0

RoBeaToZ
RoBeaToZ

Reputation: 1263

Neither Function<SomeObject, U> mapper nor SomeObject know the DummySupplier. This information must be placed somewhere, for example in a SpecializedServiceBuilder:

public class SpecializedServiceBuilder<U> extends ServiceBuilder<SomeObject, U> {

    ServiceBuilder withSomeObjectFunction(Function<SomeObject, U> mapper) {
        this.supplier = new DummySupplier();
        this.mapper = mapper;
        return this;
    }
}

Upvotes: 1

Related Questions