Path: csiph.com!usenet.pasdenom.info!weretis.net!feeder4.news.weretis.net!newsfeed.datemas.de!eternal-september.org!feeder.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Steven Simpson Newsgroups: comp.lang.java.programmer Subject: Re: Interface with implied Constructor Date: Sat, 27 Jul 2013 04:06:19 +0100 Organization: A noiseless patient Spider Lines: 61 Message-ID: References: <925adeb1-65b5-4a50-86a8-4f04784f8da0@googlegroups.com> <1KhGt.130731$7o1.74691@fx17.iad> <852ru8909m1p1eqcnhpotjpbmv1dd5hmui@4ax.com> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Injection-Info: mx05.eternal-september.org; posting-host="c129f908d169754b1d177bfcc165e288"; logging-data="8470"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19VSXbZAYfhLlEq+9tv/bjRCe+CAWG7oqs=" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130623 Thunderbird/17.0.7 In-Reply-To: Cancel-Lock: sha1:DB2IF3ELp4Ew0OgrGUXtyBqVgY4= Xref: csiph.com comp.lang.java.programmer:24848 On 23/07/13 22:32, Gene Wirchenko wrote: > I would like to have > Java enforce constructor signatures. In following this thread, I'm finding this desire for interface constructors totally bizarre. I wouldn't be surprised if I once (briefly) wanted them, but now I immediately think 'factory interface', concoct something, and find it totally satisfactory. If you want to be able to create a Foo from an argument list, define an interface type to express it: interface FooFactory { Foo createFoo(int x, int y); } It totally decouples construction from the functionality of a Foo. The FooFactory implementation just acts as an adapter between the available arguments and the configuration required by a particular Foo implementation's constructors. Not all of the configuration needs to come from the arguments; fill in missing parts with constants or get them from the environment. Not all arguments need to be used. The factory could choose different constructors depending on argument values, or return cached/pooled objects if that's compatible with the factory type's informal contract, or pass in some arguments via the constructor and others via reconfiguration methods. Multiple FooFactory implementations could use the same Foo implementation. Multiple factory types could be used when there are multiple contexts (with varying available arguments) that all, nevertheless, demand the creation of a Foo. Coding to use a factory in the dynamic case (where a factory class's name is given as a string) is simple: Foo foo = Class.forName(clazzName) .asSubclass(FooFactory.class) .getConstructor() .newInstance() .createFoo(x, y); This is type-safe and easy to refactor the argument list. If you had a way to impose a constructor Foo(int x, int y) on all Foo implementations, what would you write instead? Foo foo = Class.forName(clazzName) .asSubclass(Foo.class) .getConstructor(new Class[] { Integer.CLASS, Integer.CLASS }) .newInstance(new Object[] { x, y }); I think this is identical to what you'd write according to the OP's preferred option, where you assume that the named class has a compatible constructor. It still lacks the type safety and refactorability of the factory code, and all you gain is the assurance that getConstructor won't fail. But is that very valuable, when either approach could fail at run time simply by naming a class that doesn't implement Foo/FooFactory, or by naming a non-existent class? -- ss at comp dot lancs dot ac dot uk