FAQ
Hi,

Here's my use-case.

// Taggable allows its implementer to add, delete and check for string-type
tags.
type Taggable interface {
   //...
}

// Attributes allows its implementer to retrieve, add, modify and delete
key-value pair attributes.
type Attributes interface {
   //...
}

// Graph describes a basic, implementation-agnostic directed graph (with
nodes and edges).
type Graph interface {
   //...
}


Now I would like to have a Graph with Attributes and/or that is Taggable.
At first I just embedded both Taggable and Attributes into Graph but then I
felt it was wrong to have interfaces too big and not flexible enough.

One way of solving my concern is to leave it as in the example above and
deal only with Graph objects, and wherever I would need it to also be
Taggable I would do a type assertion for whichever particular interface I
need. The downside of that method is that there is no compile-time type
checking.
For that I would need to actually create all the combination of interfaces
and I'm fine with that. The problem is the naming. Should I create
AttributesGraph and TaggableGraph and AttributesTaggableGraph?

Thanks,
Tibor

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Search Discussions

  • William Kennedy at Jul 26, 2013 at 1:24 pm
    Tibor,

    Take a look at this from a different angle. An Interface defines behavior
    not state. So use language that represents behavior.

    You have three distinct behaviors that your framework needs to execute.

    One behavior allows for the add, delete and checking of string-type tags

    type Tagger interface {
       AddTag()
       DeleteTag()
       CheckTag()
    }

    The other behavior works on key-value attribute pairs

    type AttributeTagger interface {
       RetrieveAttr()
       AddAttr()
       ModifyAttr()
       DeleteAttr()
    }

    The last behavior has graphing capabilities

    type Grapher interface {
       AddGraph()
       DeleteGraph()
    }

    Your question is a bit confusing for me to answer because I don't
    understand the logic or the framework you wish to employ. How this behavior
    is leveraged. So let me give you some food for thought.

    If we create a variable of type Tagger what do we have? We have a variable
    that can hold a reference to an object that implements Tagger. Tagger is a
    type that only knows about Tagger functions. I can only use that variable
    to call Tagger methods.

    This assumes MyType implements all of the Tagger interface functions:

    var tagger Tagger = new(MyType)
    tagger.AddTag()

    This assumes that MyType also implements all of the AttributeTagger
    interface functions:

    var attrTagger AttributeTagger = new(MyType)
    attrTagger.AddAttr()

    The compiler will complain with this assignment if MyType does not
    implement the entire interface.

    For me the questions are:
    1. How does your processing logic work?
    2. How extendible does the framework need to be?
    3. What types of behavior does the framework perform that need to be
    abstracted?

    It is your framework code that will be requesting references to objects
    based on these published interfaces.

    The framework is using these interfaces to create polymorphic behavior in
    your app.

    In my repository I have a sample project called NewsSearch that implements
    a plugin framework. Take a look at that, it may help foster ideas.

    https://github.com/ardan-bkennedy/GoingGo

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Tibor at Jul 26, 2013 at 11:38 pm
    Thank you very much William for taking your time to answer my question!

    I am sorry if I was not clear enough in my original post. I think I do
    understand the concept of interfaces and interface embedding; the debate I
    would like to launch here is more about naming conventions for interfaces,
    and more specifically embedding interfaces.
    I truly believe that naming is one of the hardest things in programming,
    especially for non-English speakers like myself. I am investigating a
    consistent way of doing that with interfaces, to honor even more Go's
    philosophy around readability and simplicity.

    Take a look at this from a different angle. An Interface defines behavior
    not state. So use language that represents behavior.
    I agree that an interface defines behavior but it does not mean it has to
    be an adjective. The behavior can be implicit to a noun and is sometimes
    more elegant (IMHO). For instance,

    type Duck interface {
       WalkLikeADuck() // or just Walk()
       QuackLikeADuck() // or just Quack()
    }

    I wouldn't want to call it Ducker (although it'd be a nice wink to
    Docker.io ^^). I wouldn't want to call it WalkAndQuackLikeADucker or, if I
    had simplified the method names to just be Walk() and Quack(), WalkQuacker
    or QuackWalker, ...

    Same thing is true for my Graph interface. Inside my package, a Graph is
    everything that implements what I consider a graph's behavior (which is
    managing nodes and edges in my case).

    type Tagger interface {
    AddTag()
    DeleteTag()
    CheckTag()
    }
    Tagger or Taggable? Subject or Object? Is everybody okay with naming
    interfaces by the generic [VERB]ER scheme even when it is weird or
    ambiguous?
    I think, that scheme could be used for one-method-long interfaces like
    fmt.Stringer.
    You also have the corner-case problem of the comparative meaning of the -er
    suffix like in "better". How would you name interface { Bet() } ?

    With Taggable I tried to express that it is something that could be tagged
    not that it can tag (presumably something ELSE).

    type AttributeTagger interface {
    RetrieveAttr()
    AddAttr()
    ModifyAttr()
    DeleteAttr()
    }
    Why do you name AttributeTagger an interface that does not embed Tagger?
    Was it on purpose or just a mistake?

    Assuming you embed Tagger in AttributeTagger, you answer my initial
    question of naming embedding interfaces. You would name TaggableGraph an
    interface that is both a Graph and a Taggable. Which is fine. The problem
    comes when I want it to embed both Taggable and Attributes. In which case,
    is it a AttributesTaggableGraph?

    The last behavior has graphing capabilities
    type Grapher interface {
    AddGraph()
    DeleteGraph()
    }
    Like I said in the beginning of this email, my Graph interface is not a
    Grapher. It handles nodes and edges. A Grapher for me would be interface {
    Graph() }.

    Hopefully I managed to be clearer this time. If not, feel free to point me
    to wherever it is not clear enough.

    For the record, here is a list of suffix meanings I extracted from a Google
    search
    result: https://docs.google.com/spreadsheet/ccc?key=0AhOYoRh8VPScdEcwSkZ4bW9lUVFsVGZkdXZ1MXFWaVE&usp=sharing

    Addendum:
    type Duck interface {
       Walk()
       Quack()
    }

    type Colorful interface {
       Color()
    }

    type Philosopher interface {
       Philosophy()
    }

    // should this be named ColorfulDuckPhilosopher, ColorfulPhilosopherDuck or
    it doesn't matter? All the other combinations seem incorrect to me.
    type ??? interface {
       Duck
       Philosopher
       Colorful
    }

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • William Kennedy at Jul 27, 2013 at 1:04 am
    I thought you were asking about implementation.

    You are correct, how you name things in your code is very important. After
    20 years I have come to one conclusion. Listen to the language you use when
    you are talking about the project, frameworks and code. I can't tell you
    how many times I have refactored names after having a conversation with
    another developer. You should be able to have a conversation and then look
    at the code and it all be there, just like you said in your conversation.

    You can develop some standards as the Go team has done already. When an
    interface only has one method the convention is to end the name of the
    interface with "er". There are other conventions as well and these are
    great starting points, but don't try to lock yourself into something.

    Your conversations have all the answers you are looking for, you just have
    to listen. Find someone to talk with when you're stuck. It always works for
    me.


    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedJul 25, '13 at 10:31p
activeJul 27, '13 at 1:04a
posts4
users2
websitegolang.org

2 users in discussion

Tibor: 2 posts William Kennedy: 2 posts

People

Translate

site design / logo © 2022 Grokbase