Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #35873 > unrolled thread

Parameterized Factory with additional parameter requires new interface?

Started bymike <mikaelpetterson@hotmail.com>
First post2016-10-27 23:51 -0700
Last post2016-10-28 16:43 -0400
Articles 7 — 5 participants

Back to article view | Back to comp.lang.java.programmer


Contents

  Parameterized Factory with additional parameter requires new interface? mike <mikaelpetterson@hotmail.com> - 2016-10-27 23:51 -0700
    Re: Parameterized Factory with additional parameter requires new interface? j4n bur53 <janburse@fastmail.fm> - 2016-10-28 10:27 +0200
    Re: Parameterized Factory with additional parameter requires new interface? Andreas Leitgeb <avl@logic.at> - 2016-10-28 11:59 +0000
    Re: Parameterized Factory with additional parameter requires new interface? Patrick Roemer <sangamon@netcologne.de> - 2016-10-28 15:17 +0200
      Re: Parameterized Factory with additional parameter requires new interface? Eric Sosman <esosman@comcast-dot-net.invalid> - 2016-10-28 11:12 -0400
        Re: Parameterized Factory with additional parameter requires new interface? j4n bur53 <janburse@fastmail.fm> - 2016-10-28 18:07 +0200
          Re: Parameterized Factory with additional parameter requires new interface? Eric Sosman <esosman@comcast-dot-net.invalid> - 2016-10-28 16:43 -0400

#35873 — Parameterized Factory with additional parameter requires new interface?

Frommike <mikaelpetterson@hotmail.com>
Date2016-10-27 23:51 -0700
SubjectParameterized Factory with additional parameter requires new interface?
Message-ID<d1c8beb2-3ef7-4965-afa0-4cb0902c02fb@googlegroups.com>
Hi,

We have the following factory interface today:

public interface Factory<T, R> {

    /**
     * Creates a new equipment type instance
     * 
     * @param resource 
     * @return equipment instance of type T
     */
    public T create(R data);
    
}


Now we need an additional create method that takes an additional parameter of type P.


public interface Factory<T, R,P> {

    /**
     * Creates a new equipment type instance
     * 
     * @param  resource
     * @return equipment instance of type T
     */
    public T create(R resource);
    
    /**
     * Creates a new equipment type instance
     * 
     * @param resource
     * @param parameter
     * @return equipment instance of type T
     */
    public T create(R resource,P parameter);
}


Then in the code I get:

Incorrect number of arguments for type Factory<T,R,P>; it cannot be parameterized with arguments <XXXtype, XXXresource>

Does this mean we have to create a new parameterized interface for each additional create() method that we have?

If that is the case can you help me understand why?

//mike

[toc] | [next] | [standalone]


#35874

Fromj4n bur53 <janburse@fastmail.fm>
Date2016-10-28 10:27 +0200
Message-ID<nuv24q$bpd$1@news.albasani.net>
In reply to#35873

http://stackoverflow.com/questions/15200362/when-to-use-single-method-interfaces-in-java



mike schrieb:
> Hi,
>
> We have the following factory interface today:
>
> public interface Factory<T, R> {
>
>      /**
>       * Creates a new equipment type instance
>       *
>       * @param resource
>       * @return equipment instance of type T
>       */
>      public T create(R data);
>
> }
>
>
> Now we need an additional create method that takes an additional parameter of type P.
>
>
> public interface Factory<T, R,P> {
>
>      /**
>       * Creates a new equipment type instance
>       *
>       * @param  resource
>       * @return equipment instance of type T
>       */
>      public T create(R resource);
>
>      /**
>       * Creates a new equipment type instance
>       *
>       * @param resource
>       * @param parameter
>       * @return equipment instance of type T
>       */
>      public T create(R resource,P parameter);
> }
>
>
> Then in the code I get:
>
> Incorrect number of arguments for type Factory<T,R,P>; it cannot be parameterized with arguments <XXXtype, XXXresource>
>
> Does this mean we have to create a new parameterized interface for each additional create() method that we have?
>
> If that is the case can you help me understand why?
>
> //mike
>

[toc] | [prev] | [next] | [standalone]


#35875

FromAndreas Leitgeb <avl@logic.at>
Date2016-10-28 11:59 +0000
Message-ID<slrno16fdm.uka.avl@login.logic.tuwien.ac.at>
In reply to#35873
mike <mikaelpetterson@hotmail.com> wrote:
> Hi,
> We have the following factory interface today:
> public interface Factory<T, R> {
>     public T create(R data);
> }
> Now we need an additional create method that takes an additional parameter of type P.
> public interface Factory<T, R,P> {
>     public T create(R resource);
>     public T create(R resource,P parameter);
> }
> Then in the code I get:
> Incorrect number of arguments for type Factory<T,R,P>;
> it cannot be parameterized with arguments <XXXtype, XXXresource>

You could either change those places to specify a dummy third 
Type argument, but I'd rather go a different route:

Give the new Factory a different name, like:

public interface SpecialFactory<T,R,P> extends Factory<T,R> {
    public T create(R resource,P parameter);
}

Then you don't need to change the places that only need the first
method.

> Does this mean we have to create a new parameterized interface
> for each additional create() method that we have?

"have to" is too strong, as you could also change all uses of Factory
to add a third (dummy) argument.

Another (equally bad) alternative would be using raw-types, Suppress-
Warnings-annotations and explicit casts.

For a cleaner solution, you should refactor your Factory hierarchy,
if there are so many extra methods to offer of which each requires
its own Type parameter. If you worry about the combinations blow
up complexity exponentially, then make a separate (non-hierarchical)

Interface for each overload, and a single implementation that 
implements all of the separate interfaces.

> If that is the case can you help me understand why?
Because Java has no optional Type parameters, 

[toc] | [prev] | [next] | [standalone]


#35876

FromPatrick Roemer <sangamon@netcologne.de>
Date2016-10-28 15:17 +0200
Message-ID<nuvj57$gus$1@newsreader4.netcologne.de>
In reply to#35873
Responding to mike:
> public interface Factory<T, R> {
> 
>     /**
>      * Creates a new equipment type instance
>      * 
>      * @param resource 
>      * @return equipment instance of type T
>      */
>     public T create(R data);
>     
> }
> 
> 
> Now we need an additional create method that takes an additional parameter of type P.
> 
> 
> public interface Factory<T, R,P> {
> 
>     /**
>      * Creates a new equipment type instance
>      * 
>      * @param  resource
>      * @return equipment instance of type T
>      */
>     public T create(R resource);
>     
>     /**
>      * Creates a new equipment type instance
>      * 
>      * @param resource
>      * @param parameter
>      * @return equipment instance of type T
>      */
>     public T create(R resource,P parameter);
> }
> 
> 
> Then in the code I get:
> 
> Incorrect number of arguments for type Factory<T,R,P>; it cannot be parameterized with arguments <XXXtype, XXXresource>

If this was valid...

Factory<XXXtype, XXXresource> factory = ...

...how should compiler (and/or runtime) handle this?

XXXresource res = ...
XXXtype t = factory.create(res, "foo");

> Does this mean we have to create a new parameterized interface for each additional create() method that we have?

What additional create() methods do you expect?

Either your new design is valid. This basically would mean that you need
a P in addition to an R to be able to create a T, but that there's an
implied default value for any conceivable P that can be used to create a
T only given an R, so the "old" method signature is kept as a
convenience for this case. Then you should be able to come up with a
legitimate (not just "dummy") concrete type for P in your existing
instantiations.

Or the two factory approaches are independent. There might be types R
where there simply is no additional P value required to create a T.
Conversely, one could imagine types R and P such that the second method
could be implemented, but not the first one, i.e. there's no default
value for P. Then these two approaches should go to different interfaces.

Best regards,
Patrick

[toc] | [prev] | [next] | [standalone]


#35877

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2016-10-28 11:12 -0400
Message-ID<nuvprg$5jd$1@dont-email.me>
In reply to#35876
On 10/28/2016 9:17 AM, Patrick Roemer wrote:
> Responding to mike:
>> public interface Factory<T, R> {
>>
>>     /**
>>      * Creates a new equipment type instance
>>      *
>>      * @param resource
>>      * @return equipment instance of type T
>>      */
>>     public T create(R data);
>>
>> }
>>
>>
>> Now we need an additional create method that takes an additional parameter of type P.
>>
>>
>> public interface Factory<T, R,P> {
>>
>>     /**
>>      * Creates a new equipment type instance
>>      *
>>      * @param  resource
>>      * @return equipment instance of type T
>>      */
>>     public T create(R resource);
>>
>>     /**
>>      * Creates a new equipment type instance
>>      *
>>      * @param resource
>>      * @param parameter
>>      * @return equipment instance of type T
>>      */
>>     public T create(R resource,P parameter);
>> }
>>
>>
>> Then in the code I get:
>>
>> Incorrect number of arguments for type Factory<T,R,P>; it cannot be parameterized with arguments <XXXtype, XXXresource>
>
> If this was valid...
>
> Factory<XXXtype, XXXresource> factory = ...
>
> ...how should compiler (and/or runtime) handle this?
>
> XXXresource res = ...
> XXXtype t = factory.create(res, "foo");
>
>> Does this mean we have to create a new parameterized interface for each additional create() method that we have?
>
> What additional create() methods do you expect?
>
> Either your new design is valid. This basically would mean that you need
> a P in addition to an R to be able to create a T, but that there's an
> implied default value for any conceivable P that can be used to create a
> T only given an R, so the "old" method signature is kept as a
> convenience for this case. Then you should be able to come up with a
> legitimate (not just "dummy") concrete type for P in your existing
> instantiations.
>
> Or the two factory approaches are independent. There might be types R
> where there simply is no additional P value required to create a T.
> Conversely, one could imagine types R and P such that the second method
> could be implemented, but not the first one, i.e. there's no default
> value for P. Then these two approaches should go to different interfaces.

     Another possibility is to "smuggle" the parameter to the factory
by packaging it with the resource:

	class Smuggler<R, P> {
	    private final R resource;
	    private final P parameter;
	    Smuggler(R resource, P parameter) {
	        this.resource = resource;
	        this.parameter = parameter;
	    }
	    R getResource() { return resource; }
	    P getParameter() { return parameter; }
	}

	class MyFactory implements Factory<T, Smuggler<R, P>> {
	    public T create(Smuggler<R, P> data) {
	        R resource = data.getResource();
	        P parameter = data.getParameter();
	       ...
	    }
	}

(Double-check my <type parameters>; I've not done so ...)

-- 
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM

[toc] | [prev] | [next] | [standalone]


#35878

Fromj4n bur53 <janburse@fastmail.fm>
Date2016-10-28 18:07 +0200
Message-ID<nuvt3j$bks$1@news.albasani.net>
In reply to#35877
Eric Sosman schrieb:
> XXXresource res = ...
> XXXtype t = factory.create(res, "foo");

You could curry differently it:

 > XXXresource res = ...
 > XXXtype t = factory.derive(res).create("foo");

-- OR --

 > XXXresource res = ...
 > XXXtype t = res.derive(factory).create("foo");

In all 3 cases you can use singletons for
factory or res.

But I guess the two parameter create() will save
you some intermediate allocate for the
builder closure.

[toc] | [prev] | [next] | [standalone]


#35879

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2016-10-28 16:43 -0400
Message-ID<nv0d9l$ld0$1@dont-email.me>
In reply to#35878
On 10/28/2016 12:07 PM, j4n bur53 wrote:
> Eric Sosman schrieb:

No, I can't take the credit: Patrick Roemer schrieb.

>> XXXresource res = ...
>> [...]

-- 
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.java.programmer


csiph-web