State interfaces
roger peppe
rogpeppe at gmail.com
Fri Nov 1 12:31:05 UTC 2013
On 31 October 2013 18:42, Andrew Wilkins <andrew.wilkins at canonical.com> wrote:
> type State interface {
> AllMachines() ([]Machine, error)
> }
>
> // another name would be needed, as this clashes with state.Entity; just for
> demonstration
> type Entity interface {
> Tag() string
> Destroy() error
> Refresh() error
> }
>
> type Machine interface {
> Entity
> Units() ([]Unit, error)
> Jobs() []MachineJob
> }
>
> type Unit interface {
> Entity
> IsPrincipal() bool
> }
>
> ----------------- 8< -------------------
>
> If it weren't for State.AllMachines and Machine.Units, I wouldn't have even
> asked the question. The problem is that these methods' signatures would need
> to change to return interfaces. Then once you do that, you're destined to
> implement everything as an interface. For the structs to implement an
> external interface, the structs (as they are now) would need to be wrapped,
> and then you're back to duplicating everything again.
There are a few possibilities here. You can make an adaptor type from State
to your interface-based type without *that* much trouble, although
the slice returns are a little awkward (and incur some runtime overhead):
http://play.golang.org/p/PlXy7ZLQYS
Another possibility, and my personal preference, would be to define
an interface that maps more closely to the exact needs of
your code (something I'm not entirely sure of here) but can still
be trivially implemented on top of State.
You would then need a test to make sure that
the code that implements that interface functions correctly,
but all the tricky logic in your code can be tested independently
of an actual State implementation.
That approach might or might not be a win in your particular case.
> Another option would be to add a couple of new methods:
> State.AllMachineNames(), and Machine.UnitNames(), which return []strings.
> This isn't great either, as it means duplicating work (at least two trips to
> the database, when one would do).
I'm not that keen on that option.
More information about the Juju-dev
mailing list