Interface with implied Constructor

D

Daniel Pitts

[...]
I'd call that "factory pattern". Why did you pick "builder"?

They're similar. I've seen the term "builder" used more often when the
construction is done by the implementor and "factory" more often when
the construction is performed by a single system. Builder also has a
pattern of SomeThing a= new
Builder().with(Options.B).add(x).add(y).addAll(Z).makeImmutable(); It's
a way to specify arguments after construction without allowing access to
a partially built object.
I would say the difference is that a builder is a type of factory which
can be configured before the factory method is invoked.

Ah, the old FactoryFactory pattern. That's the second time
it's been pulled on me this week!

(Sorry about that, Chief.)
No, it isn't a Factory Factory.

A builder is a single factory. That factory can be configured before it
is invoked to produce its output.

A factory builder or a factory factory is a different concept. It is
possibly, but not necessarily, an antipattern indicating that you've
abstracted too far.
 
A

Arved Sandstrom

Using a constructor to initialize an object does not make it necessary
to do that via reflection. You can have the same functionality simpler
with a factory.


Either throw IllegalStateException or use a single method for
initialization right away.


Hammers are useful tools - but I usually don't use them to fix a screw.


I opted for the init() method OR factory method pattern. Both are type
safe because in both cases a method in an interface needs to be
implemented. Picking a constructor solely based on argument types has a
looser coupling between the contract and the implementation of it. An
interface makes that coupling explicit.

Cheers

robert
I'll be honest, Robert, personally I consider the behaviour of an object
- the kinds of things you could specify in an interface - to be what the
*initialized* object can (should) do.

I seriously dislike init() methods, not just in Java. Particularly if
there is no sensible un-init()'ed object for the class. I just don't see
any credible argument for them. Like Richard said, actually: "half-baked".

Often the best way to properly initialize an object is to call a
constructor with arguments. That's what they are for. And to be honest
once again, a ctor *is* an implementation thing, IMO: it's not the
business of an interface to dictate how an implementation will
initialize objects that can support the interface contract. After all,
how can an interface even possibly imagine what the internal state of an
initialized object, hence what ctor args are required, is?

No problem with factory methods, except they are for specific
situations. And I think they also lean more towards implementation.

AHS
 
G

Gene Wirchenko

On Thu, 18 Jul 2013 23:21:35 -0300, Arved Sandstrom

[snip]
I'll be honest, Robert, personally I consider the behaviour of an object
- the kinds of things you could specify in an interface - to be what the
*initialized* object can (should) do.

But there is more to it than that. There is also getting it
initialised. That should also be part of the API. I would not
enforce that it has to, but I sure would like the option to specify
constructor signatures in an interface.
I seriously dislike init() methods, not just in Java. Particularly if
there is no sensible un-init()'ed object for the class. I just don't see
any credible argument for them. Like Richard said, actually: "half-baked".

Often the best way to properly initialize an object is to call a
constructor with arguments. That's what they are for. And to be honest
once again, a ctor *is* an implementation thing, IMO: it's not the

A method is an implementation thing, too, but we have interface
specifications for them.
business of an interface to dictate how an implementation will
initialize objects that can support the interface contract. After all,

That is exactly what it is for. How the implementation works is
not the business of the interface, but how to call it is.
how can an interface even possibly imagine what the internal state of an
initialized object, hence what ctor args are required, is?

Internal state is implementation and so is not in an interface's
scope. How to call it is.
No problem with factory methods, except they are for specific
situations. And I think they also lean more towards implementation.

Sincerely,

Gene Wirchenko
 
A

Arved Sandstrom

On Thu, 18 Jul 2013 23:21:35 -0300, Arved Sandstrom

[snip]
I'll be honest, Robert, personally I consider the behaviour of an object
- the kinds of things you could specify in an interface - to be what the
*initialized* object can (should) do.

But there is more to it than that. There is also getting it
initialised. That should also be part of the API. I would not
enforce that it has to, but I sure would like the option to specify
constructor signatures in an interface.

Apart from other problems with constructors in interfaces (e.g. a class
implements 2 interfaces, both of which have constructors: which ctor do
you ignore and hence violate a contract?), what do you intend to mandate
by requiring a constructor with a given signature? That all implementing
classes create matching private fields that are exposed by accessors?
Why would you want to do that?

Although it's usually an anti-pattern, I believe a better idea would be
to specify some important getters in an interface, if you need something
like this. Rather than wanting to control how an object initializes
itself and is implemented, typically what you're really after is to
require that an object can provide some synthetic state information.
A method is an implementation thing, too, but we have interface
specifications for them.

The *body* of a method is implementation. Interface or no interface, the
method as called, the way it represents to callers, is behaviour.

I've seen people in threads make your argument. To call everything
behaviour is not helpful. A constructor builds an object. I don't
consider that behaviour.
That is exactly what it is for. How the implementation works is
not the business of the interface, but how to call it is.

I don't consider a constructor a "call". Invoking a method on a properly
initialized method, yes; *building* the object, no.
Internal state is implementation and so is not in an interface's
scope. How to call it is.


Sincerely,

Gene Wirchenko
AHS
 
A

Arved Sandstrom

On Thu, 18 Jul 2013 23:21:35 -0300, Arved Sandstrom

[snip]
I'll be honest, Robert, personally I consider the behaviour of an object
- the kinds of things you could specify in an interface - to be what the
*initialized* object can (should) do.

But there is more to it than that. There is also getting it
initialised. That should also be part of the API. I would not enforce
that it has to, but I sure would like the option to specify constructor
signatures in an interface.
Yes, agreed. I tend to extend superclasses instead of using an interface
for exactly that reason.
[ SNIP ]

Which is one reason you use abstract classes. If you want to supply
constructors, implement them, and put them in an abstract class. It's
the right place: in my continuing opinion ctors are an implementation
detail.

AHS
 
E

Eric Sosman

[...]
Which is one reason you use abstract classes. If you want to supply
constructors, implement them, and put them in an abstract class. It's
the right place: in my continuing opinion ctors are an implementation
detail.

Uhm, sorry, I don't get it. Such a constructor would only
be callable from the constructor of a subclass, and there's still
nothing to require that the subclass provide any particular style
of constructor.

(As mentioned elsethread I don't think interface-mandated
constructors would be useful. I'm just wondering how you'd use
abstract classes to achieve the not-so-useful effect.)
 
A

Arved Sandstrom

[...]
Which is one reason you use abstract classes. If you want to supply
constructors, implement them, and put them in an abstract class. It's
the right place: in my continuing opinion ctors are an implementation
detail.

Uhm, sorry, I don't get it. Such a constructor would only
be callable from the constructor of a subclass, and there's still
nothing to require that the subclass provide any particular style
of constructor.

(As mentioned elsethread I don't think interface-mandated
constructors would be useful. I'm just wondering how you'd use
abstract classes to achieve the not-so-useful effect.)
Sure, it's imperfect. The best you can hope for is the the subclass uses
one of the provided constructors. It works reasonably well with Exception.

But like I said I don't think much of any system that attempts to
mandate how a class builds itself. I always figured that was up to the
class itself.

AHS
 
K

Kevin McMurtrie

Martin Gregorie said:
On Thu, 18 Jul 2013 23:21:35 -0300, Arved Sandstrom

[snip]
I'll be honest, Robert, personally I consider the behaviour of an object
- the kinds of things you could specify in an interface - to be what the
*initialized* object can (should) do.

But there is more to it than that. There is also getting it
initialised. That should also be part of the API. I would not enforce
that it has to, but I sure would like the option to specify constructor
signatures in an interface.
Yes, agreed. I tend to extend superclasses instead of using an interface
for exactly that reason.

I take the opposite approach to Robert over that for one reason: that the
only way to report init errors in a constructor is to throw an Exception,
which means the instance declaration often needs to go inside a try/catch
block which can screw up scoping. If init errors are possible and must be
caught, I prefer to use a constructor that can't do anything that needs
an Exception to be thrown and finish the job with an init() method that
can go in the following try/catch block along with (some of) the other
method calls.

You never want public constructors that produce incomplete objects.
They pollute your application and cause recurring failures long after
the original fault. It's too difficult to debug all the places where
the object is constructed and possibly leaks out of scope without full
initialization. It's best if the minimum requirements for an object's
functionality are assigned in the constructor and 'final'.

I only use initialization methods for private implementations where it's
easy to control the scope of an uninitialized object. A typical case is
where a new cached object takes a very long time to initialize.
Simplified example:


private final HashMap<String, CachableThing> cache=
new HashMap<String, CachableThing>();

private static class CachableThing implements Thing
{ ... }

public Thing getThing(String key) throws SomeException
{
CachableThing t;
synchronized (cache)
{
t= cache.get(key);
if (t == null)
cache.put(key, t= new CachableThing());
}

synchronized (t)
{
if (!t.initialized())
t.init(key); //Very slow and may intermittently throw
}

return t;
}
 
M

markspace

You never want public constructors that produce incomplete objects.
They pollute your application and cause recurring failures long after
the original fault. It's too difficult to debug all the places where


While I think you have some good points here, I also think it's OK to
design an object or interface with a defined life-cycle.

For example a plain Socket must connected before it can be meaningfully
used.

Socket sock = new Socket();
sock.connect( ... );

(Likewise the socket must be closed also.)

While not exactly the same as a generic init() method, it's along the
same idea, and I don't see Java programs in general "polluted" with
partially constructed sockets.

Files and Paths take a slightly different approach; they use static
methods in the Files class to get a stream (or File uses the
FileI/OStream classes). I'm not sure I like this however. Why wouldn't
a basic open() method on the File object just be easier?

So there's three different ways: lifecycle (i.e., open/close), static
method (Files) and ctor for another helper class (like FileI/OStream).
The lifecycle option seems the most straight forward to me.
 
R

Richard Maher

While not exactly the same as a generic init() method, it's along the
same idea, and I don't see Java programs in general "polluted" with
partially constructed sockets.

Sockets are stateful without connections.
Files and Paths take a slightly different approach; they use static
methods in the Files class to get a stream (or File uses the
FileI/OStream classes). I'm not sure I like this however. Why wouldn't
a basic open() method on the File object just be easier?

So there's three different ways: lifecycle (i.e., open/close), static
method (Files) and ctor for another helper class (like FileI/OStream).
The lifecycle option seems the most straight forward to me.

On the subject of close() and reason now why any such classes should not
implement java.lang.AutoCloseable? Idempotency not withstanding.

Anyway for the sake of narrowing this thread her is the interface I'm
asking the user to implement: -

/**
* Copyright Tier3 (c) Software. All rights reserved.
*
* Contract for user class that will specify and process
* the server handshake.
*
* @author Richard Maher
* @version 1.0
*
*/

package tier3Client;

import java.awt.Color;
import java.lang.AutoCloseable;

interface Tier3Handshake extends AutoCloseable{

String getSalutation();

boolean setResponse(String remoteResp);

void setRcvd(int bytes);

void setSent(int bytes);

void setRefCnt(int pages);

void appendMsg(String msg, Color color);

void appendMsg(String msg);

}
 
R

Richard Maher

[...]
Which is one reason you use abstract classes. If you want to supply
constructors, implement them, and put them in an abstract class. It's
the right place: in my continuing opinion ctors are an implementation
detail.

Uhm, sorry, I don't get it. Such a constructor would only
be callable from the constructor of a subclass, and there's still
nothing to require that the subclass provide any particular style
of constructor.

(As mentioned elsethread I don't think interface-mandated
constructors would be useful. I'm just wondering how you'd use
abstract classes to achieve the not-so-useful effect.)
Sure, it's imperfect. The best you can hope for is the the subclass uses
one of the provided constructors. It works reasonably well with Exception.

But like I said I don't think much of any system that attempts to
mandate how a class builds itself. I always figured that was up to the
class itself.

I didn't say "mandated" and I'm not sure anyone else did besides yourself.

In the case of my Applet where I'm controlling the mainline (via and
init() method ironically enough). The user-supplied class, for getting
things like username/password etc and optionally displaying a console
window, is going to be pretty specialized. However, if a generic(ish)
class you have happens to provide an opportunity for code re-use then
that's peachy. The closest I get to "mandatory" is to say "Regardless of
any other constructors, I require you to provide either an empty
constructor or one which takes a Tier3Ambience object as its only
parameter".

If you're all so in love with init() methods then after setting
non-standard-constructor-init-reqd = true in the constructor, your
getSalutation() method can call all the functionality it wants even
passing "this" for callbacks if it so desires.

For dynamically, run-time loaded, code I just like my method. If you'd
prefer not to avail yourselves of all the lovely methods that
Tier3Ambience makes visible to you then don't use it.

Cheers Richard Maher
 
A

Arved Sandstrom

On 7/19/2013 5:56 PM, Arved Sandstrom wrote:
[...]
Which is one reason you use abstract classes. If you want to supply
constructors, implement them, and put them in an abstract class. It's
the right place: in my continuing opinion ctors are an implementation
detail.

Uhm, sorry, I don't get it. Such a constructor would only
be callable from the constructor of a subclass, and there's still
nothing to require that the subclass provide any particular style
of constructor.

(As mentioned elsethread I don't think interface-mandated
constructors would be useful. I'm just wondering how you'd use
abstract classes to achieve the not-so-useful effect.)
Sure, it's imperfect. The best you can hope for is the the subclass uses
one of the provided constructors. It works reasonably well with
Exception.

But like I said I don't think much of any system that attempts to
mandate how a class builds itself. I always figured that was up to the
class itself.

I didn't say "mandated" and I'm not sure anyone else did besides yourself.
[ SNIP ]

I wasn't necessarily replying directly to you. But an interface
*mandates*, and so if you were somehow able to put constructors in an
interface, they'd be mandated.
If you're all so in love with init() methods then after setting
non-standard-constructor-init-reqd = true in the constructor, your
getSalutation() method can call all the functionality it wants even
passing "this" for callbacks if it so desires.

The "you're all" doesn't include me. I haven't used any form of init()
method for a long time.
For dynamically, run-time loaded, code I just like my method. If you'd
prefer not to avail yourselves of all the lovely methods that
Tier3Ambience makes visible to you then don't use it.

Cheers Richard Maher

For what it's worth I have done more or less what you are doing, using
reflection and locating a constructor with certain argument types, a
number of times. Most recently, to convert results of JPA native queries
into lists of non-entity objects.

AHS
 
A

Arved Sandstrom

While I think you have some good points here, I also think it's OK to
design an object or interface with a defined life-cycle.

For example a plain Socket must connected before it can be meaningfully
used.

Socket sock = new Socket();
sock.connect( ... );

(Likewise the socket must be closed also.)

While not exactly the same as a generic init() method, it's along the
same idea, and I don't see Java programs in general "polluted" with
partially constructed sockets.
[ SNIP ]

You do see Java programs littered with pairs of the 2 statements you
just described. With the appropriate Socket ctor you'd have one statement.

It's a matter of debate as to whether a "new Socket()" is partially
constructed or not. I'd say that it is, it doesn't know how to do
anything much useful at that point. If your motivation is to set certain
connection options, before connecting, java.net.Socket has better
approaches.

AHS
 
E

Eric Sosman

[...]
But like I said I don't think much of any system that attempts to
mandate how a class builds itself. I always figured that was up to the
class itself.

I didn't say "mandated" and I'm not sure anyone else did besides yourself.

In the case of my Applet where I'm controlling the mainline (via and
init() method ironically enough). The user-supplied class, for getting
things like username/password etc and optionally displaying a console
window, is going to be pretty specialized. However, if a generic(ish)
class you have happens to provide an opportunity for code re-use then
that's peachy. The closest I get to "mandatory" is to say "Regardless of
any other constructors, I require you to provide either an empty
constructor or one which takes a Tier3Ambience object as its only
parameter".

So: Not "mandatory," but "required." Subtle.

Is this like the United States' "voluntary" income tax payments?
(You don't *have* to pay the tax, but if you don't the government
may garnish your wages, seize your property, and/or put you in jail.
The choice is entirely yours, to make as freely as you please.)
 
R

Robert Klemme

Just for the record: I am also not very fond of init methods. But I
don't condemn them either. It's not too unusual to require specific
order of method invocations in an interface. For example you need to
have invoked java.util.List.add() once before List.get(0) can return
anything meaningful.
I take the opposite approach to Robert over that for one reason: that the
only way to report init errors in a constructor is to throw an Exception,
which means the instance declaration often needs to go inside a try/catch
block which can screw up scoping.

In what ways does this screw up scoping?
If init errors are possible and must be
caught, I prefer to use a constructor that can't do anything that needs
an Exception to be thrown and finish the job with an init() method that
can go in the following try/catch block along with (some of) the other
method calls.

From your description I am not sure I understood the pattern you are
advertising here. Can you show this in code? The thing which irritates
me is that you want to have a "following try/catch" block. What for?

Kind regards

robert
 
R

Robert Klemme

I'll be honest, Robert, personally I consider the behaviour of an object
- the kinds of things you could specify in an interface - to be what the
*initialized* object can (should) do.

Of course. A factory instance can also be an initialized object.
Often the best way to properly initialize an object is to call a
constructor with arguments. That's what they are for. And to be honest
once again, a ctor *is* an implementation thing, IMO: it's not the
business of an interface to dictate how an implementation will
initialize objects that can support the interface contract. After all,
how can an interface even possibly imagine what the internal state of an
initialized object, hence what ctor args are required, is?

In situations like Richard's (at least as I understand it) the
environment knows what information it has available and the interface
for the factory can be defined in such a way to pass data potentially
needed or the data that the environment is willing to provide. The
factory implementation then can decide which part of that information is
needed to create the instance and ignore the rest. It's surely better
to let the implementor of the construction process decide which
information to use than the implementor of the environment (or call it
"framework").
No problem with factory methods, except they are for specific
situations. And I think they also lean more towards implementation.

What "specific situations" do you have in mind? As far as I can see the
name of the class to create is configured and Richard said reflection
will be used in his initial posting. I think that is a typical
situation where a factory class can be configured which is created via a
no arg constructor and which has a method createFoo(...) with
appropriate arguments. Then there is no need to fiddle with reflection
to analyze constructors and argument lists. Also, this gives more
flexibility as the factory can decide which class to instantiate at
runtime if need be.

My main point is that I dislike using reflection to _find_ an
appropriate method - be it a constructor or another method. I prefer
that method to be identified in an interface - whether that is an init()
method in the interface of the object I will eventually be using or a
create() method in another interface defining the factory API I care
less. I think Class.forName() and newInstance() is enough reflection to
get flexibility and decoupling but from there on I prefer to use methods
specified via an interface or abstract base class.

Kind regards

robert
 
R

Robert Klemme

Of course. A factory instance can also be an initialized object.


In situations like Richard's (at least as I understand it) the
environment knows what information it has available and the interface
for the factory can be defined in such a way to pass data potentially
needed or the data that the environment is willing to provide. The
factory implementation then can decide which part of that information is
needed to create the instance and ignore the rest. It's surely better
to let the implementor of the construction process decide which
information to use than the implementor of the environment (or call it
"framework").


What "specific situations" do you have in mind? As far as I can see the
name of the class to create is configured and Richard said reflection
will be used in his initial posting. I think that is a typical
situation where a factory class can be configured which is created via a
no arg constructor and which has a method createFoo(...) with
appropriate arguments. Then there is no need to fiddle with reflection
to analyze constructors and argument lists. Also, this gives more
flexibility as the factory can decide which class to instantiate at
runtime if need be.

My main point is that I dislike using reflection to _find_ an
appropriate method - be it a constructor or another method. I prefer
that method to be identified in an interface - whether that is an init()
method in the interface of the object I will eventually be using or a
create() method in another interface defining the factory API I care
less. I think Class.forName() and newInstance() is enough reflection to
get flexibility and decoupling but from there on I prefer to use methods
specified via an interface or abstract base class.

Adding one bit of reasoning: the reason I dislike the approach to find a
method via reflection is that the contract is documented in text only
("the class must have at least a constructor with these argument
types...") whereas with an interface the contract is expressed in code
as far as possible. (With that I mean there are other languages which
allow to define much more aspects of a contract in code, like Eiffel.)
That makes better use of language features IMO.

Cheers

robert
 
E

Eric Sosman

[...]
I take the opposite approach to Robert over that for one reason: that
the only way to report init errors in a constructor is to throw an
Exception,
which means the instance declaration often needs to go inside a
try/catch block which can screw up scoping.

In what ways does this screw up scoping?
Just that I often find that I need access to the instance outside the try/
catch block containing the constructor call and I don't much like
initialising the pointer as null.

Then ... don't initialize it.

Thing thing;
try {
thing = new Thing();
} catch (DooWopDooWopDooWopException ex) {
logger.log(Level.SEVERE, "Eek!", ex);
throw ex;
}
System.out.println(thing.getSwing());
...

This form has the advantage that the compiler will complain if
the all-important `throw ex;' is forgotten, whereas initializing
to null would just get you an NPE.

Very occasionally there's a situation where you really do need
to use the null-ness of `thing' as an indication that construction
failed. In that case, I'd still suggest not initializing:

Thing thing;
try {
thing = new Thing();
} catch (DooWopDooWopDooWopException ex) {
logger.log(Level.SEVERE, "Eek!", ex);
thing = null;
}
if (thing != null) {
System.out.println(thing.getSwing());
else {
System.out.println("It don't mean a thing");
}

IMHO, situations like this are suggestive of a poorly-designed
Thing class (which you may be forced to endure), or of a method
that's trying to do too many things and might better be split up.
This is a result of my dislike of using Exceptions to signal anything
except a fatal error and may well be a hangover from writing a lot of C
in the past. A method that returns reference to a library class whose
constructor can throw an exception, e.g. Integer, but does not itself
return an exception requires this sort of structure:

public class Altitude
{
int alt = 0;
String error = null;

/**
* Returning a negative number indicates an invalid height.
*/
public int getHeight(String height)
{
Integer h = null;

Since this initialization is useless (the variable will
always be overwritten, exception or no), why even have it?
try
{
h = new Integer(height);
if (h < 0)
error = "Below MSL";
}
catch (NumberFormatException e)
{
error = e.getMessage();
h = new Integer(-1);
}

return alt = h.intValue();
}

public boolean isValid()
{ return error === null; }

public String getError()
{ return error; }
}

This isn't a really good example because Integer provides other ways of
doing the job, but it does illustrate the sort of scoping problem I'm
talking about: that of allowing access to the Integer instance in both
parts of the try/catch block as well as from surrounding parts of the
method body.

I don't see how the NumberFormatException has much to do
with it: Your getHeight() method needs the `h' at the point
of its return, so its scope must include the return statement.
The only "scoping issue" I can see is that the try block and the
catch block have their own subsidiary scopes in which `h' also
needs to be (and is) visible -- but then, why aren't you worried
about the scope of `height'? (Or even of `error' and `alt'?)
 
J

Joerg Meier

My main point is that I dislike using reflection to _find_ an
appropriate method - be it a constructor or another method. I prefer
that method to be identified in an interface - whether that is an init()
method in the interface of the object I will eventually be using or a
create() method in another interface defining the factory API I care
less. I think Class.forName() and newInstance() is enough reflection to
get flexibility and decoupling but from there on I prefer to use methods
specified via an interface or abstract base class.

While I have admittedly not followed the whole thread too closely, how
about this ?

public interface Bla {
public void setBlurg(int newBlurg);

public int getBlurg();

public Bla getInstance(int param, float difParam, Socket sockParam);
}

No more need for Reflection to search for something. On the implementation
level, getInstance can still decide to discard unneccessary parameters.

Liebe Gruesse,
Joerg
 
E

Eric Sosman

[...]
While I have admittedly not followed the whole thread too closely, how
about this ?

public interface Bla {
public void setBlurg(int newBlurg);

public int getBlurg();

public Bla getInstance(int param, float difParam, Socket sockParam);
}

No more need for Reflection to search for something. On the implementation
level, getInstance can still decide to discard unneccessary parameters.

Since you already need an instance of a class implementing
Bla before you can call getInstance() on it, what's the point?

Perhaps you meant the interface to be BlaFactory (with getInstance()
still returning Bla)?

BlaFactory factory = BlaFactoryProvider.defaultFactory();
factory.setBlurg(86);
Bla instance = factory.getInstance(42, 42.0, null);
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,736
Latest member
AdolphBig6

Latest Threads

Top