On Tue, Dec 17, 2013 at 1:11 PM, Travis Keep <
kee...@gmail.com> wrote:
> I have a go type that represents a connection to a home automation center.
> As new functionality is offered, more methods will be added to this class.
>
> There is a configurable event manager that wraps one of these connection
> instances and runs commands on it at specified times or when specified
> events happen.
>
> My event manager could take a connection object, but that makes the API too
> narrow. What if client wants to do testing with a mock or a fake? What if
> client wants to log events?
> I could create an interface with all the methods, but the connection type
> will get new methods. The interface that I create today won't expose all the
> functionality on the connection object tomorrow. To get to new functionality
> not in the interface, type assertions would be needed.
The general rule with interfaces is to declare the minimum you need.
If you later need more and want to expand the functionality without breaking
current users then you'll need some kind of default behaviour for
interface methods required by the new functionality.
A few packages start with a minimal interface and then do type
assertions to try to expand it.
This has some problems (incorrectly assuming methods with the right
signature are there to implement the interface) but it's a reasonable
solution.
If you're going this route you should document the interfaces you're
expanding to and make sure the methods in
them are rather unique to reduce the chance of unrelated methods
accidentally implementing the interface.
The other solution is to have a new function for the additional
functionality that takes the expanded interface
and possibly a wrapper type that implements defaults for the new
methods to make it easier for users to
transition to the new API without having to implement the additional
methods on all their types.