Naming convention for structs which implement interfaces

5,184 views
Skip to first unread message

Eric Hawthorne

unread,
Jun 28, 2010, 7:34:39 PM6/28/10
to golang-nuts
An idiot in search of an idiom...

I imagine that it is not controversial that calling code should
declare variables, parameters as being instances of some interface or
other if possible, as opposed to declaring the variables, parameters
to be instances of specific struct types. The calling code is thus
more general and re-usable, extensible etc.

So it would seem that interfaces should have natural-language-readable
type-names, in the spirit of literate programming.

So this is bad:
type MessageParserIntfc interface

and this is good:
type MessageParser interface

What is the recommended way of naming struct types which implement the
interface, but yet must still be exported because they have a few
extra methods.

Do you just find a suitable prefix for the struct type name, such as

ReallyFastMessageParser

or

BaseMessageParser

or

HtmlMessageParser

(Even though I can't straightforwardly tell that I'm dealing with a
struct type here from the name)

Or do you just always put your structs in a different package and use
the package name to
differentiate when necessary? Seems awkward and error prone.

Or does anyone have any other suggested best practices?

Surely not the java-ish MessageParserImpl ?

Russ Cox

unread,
Jun 28, 2010, 8:03:15 PM6/28/10
to Eric Hawthorne, golang-nuts
> I imagine that it is not controversial that calling code should
> declare variables, parameters as being instances of some interface or
> other if possible, as opposed to declaring the variables, parameters
> to be instances of specific struct types. The calling code is thus
> more general and re-usable, extensible etc.

I disagree.

Trying to distinguish a 10-method interface from a
12-method struct implementing that interface is
probably more pain than it's worth.

Russ

Andrew Gerrand

unread,
Jun 29, 2010, 12:19:40 AM6/29/10
to Eric Hawthorne, golang-nuts
On 29 June 2010 09:34, Eric Hawthorne <poetics...@gmail.com> wrote:
> Or does anyone have any other suggested best practices?

An interface should describe what it does. For example, Reader, Writer.

Similarly, a type should describe what it is. For example,
json.Encoder, http.Request. A type may implement more than one
interface, so naming your type after the interfaces it implements will
lead to painfully verbose naming.

To summarize: when naming a type, use the simplest name that can be
understood in the context of the package.
(ie, json.Encode, not json.JsonEncoder)

Andrew

Eric Hawthorne

unread,
Jun 29, 2010, 12:28:08 PM6/29/10
to golang-nuts
Russ Cox disagreed with my deliberately provocative suggestion to
write calling code to refer to interfaces instead of concrete types.

The counterexample you gave is pretty extreme (in the tail of the
distribution of interface definitions).

The way I would put it is, if you are writing a toss-off or one-off
program and you cannot imagine anyone will want to extend it, then
maybe just write all your code to be exactly as specific as you need
it right now. But are you sure about your supposition? Remember that
most expense comes in maintaining and extending/modifying code
long after it was originally written.

Eric Hawthorne

unread,
Jun 29, 2010, 12:36:39 PM6/29/10
to golang-nuts
Andrew Gerrand wrote:

> An interface should describe what it does. For example, Reader, Writer.
> Similarly, a type should describe what it is.

"Stupid is as stupid does." :-)

No seriously, I don't think that suggestion can provide a basis for
distinction,
since many types (irrespective of whether a concrete implementation is
provided
or not) define an entity or concept whose essence is what it does.

E.g. is HotWaterHeater an interface or a struct type?

Providing an interface is a statement to future programmers that "here
is
an important bundle of behaviors, and I am expressly pointing out that
there could be many ways of implementing this set of behaviors". i.e.
I the original programmer are both suggesting to you you might want
to
reuse and vary the implementation of this concept/behavior, and I am
allowing you to do so easily while remaining compatible with other
code
I have written that targets my interface.

There are many cases where I as original programmer want to program
in this "farsighted" way, and yet have only a single implementing
struct type
at the moment. That is the context in which my question about type
name conventions
comes up. It should be a pretty common case.




On Jun 28, 9:19 pm, Andrew Gerrand <a...@golang.org> wrote:

Russ Cox

unread,
Jun 29, 2010, 12:50:08 PM6/29/10
to Eric Hawthorne, golang-nuts
On Tue, Jun 29, 2010 at 09:28, Eric Hawthorne <poetics...@gmail.com> wrote:
> Russ Cox disagreed with my deliberately provocative suggestion to
> write calling code to refer to interfaces instead of concrete types.
>
> The counterexample you gave is pretty extreme (in the tail of the
> distribution of interface definitions).

In other languages, sure. But not in Go.
Look around the source tree: most functions only need
one or two methods from the object being passed in,
and those use a precise interface. Part of the reason
it's okay to be so precise is that there is no tight
coupling (like in Java) between the implementations
and the interfaces: the implementations don't have to
list every interface they're implementing. We talked
about this quite a bit in the Google I/O talk:
http://www.youtube.com/watch?v=jgVhBThJdXc

> The way I would put it is, if you are writing a toss-off or one-off
> program and you cannot imagine anyone will want to extend it, then
> maybe just write all your code to be exactly as specific as you need
> it right now. But are you sure about your supposition? Remember that
> most expense comes in maintaining and extending/modifying code
> long after it was originally written.

Obviously, we like interfaces. But it's easy to change,
even retrofit, existing code to accept interfaces later,
with minimal changes in the callers (see video),
so agonizing over this decision right now may not be
the best use of time.

It's also very hard (easy?) to argue over generalities. I tried to
be concrete in my reply (10-method interface vs 12-method struct)
but it would help focus the discussion if you could be more
specific about the case you have in mind. It seems unlikely
you are actually coding a HotWaterHeater.

In my own programs I've found that the interface and
concrete types often end up in different packages, which
can provide another answer to your question. For example,
the Cipher interface in the crypto/block package is
implemented by the Cipher type in the crypto/aes and
crypto/blowfish subdirectories. I haven't felt a need to
mangle either name to try to distinguish them. There are already
good tools for learning about types (godoc crypto/block Cipher;
godoc crypto/aes Cipher), I'm sure integration with
IDEs will improve over time, and the qualified names give
useful hints as to the generality of the type:
block.Cipher vs aes.Cipher.

Russ

Reply all
Reply to author
Forward
0 new messages