Go for Classic OO: Difference between revisions
Adamcolton (talk | contribs) No edit summary |
Adamcolton (talk | contribs) No edit summary |
||
| Line 25: | Line 25: | ||
== Techniques == | == Techniques == | ||
=== Staying DRY === | |||
==== Pluggable Method ==== | |||
Put a func field on the struct and have one of the methods wrap a call to that. | |||
Sorter example | |||
==== Pluggable Interface ==== | |||
Put an interface field on the struct and | |||
==== Embed Interface ==== | |||
Embed an interface. | |||
=== Privacy Tricks === | === Privacy Tricks === | ||
==== Getters and Setters ==== | |||
Go does not have an explicit getter/setter pattern, but they are used frequently to access private fields. | |||
==== Private abstract ==== | ==== Private abstract ==== | ||
Revision as of 16:45, 11 August 2016
Key Difference
- Private is package wide
- structs are concrete, interfaces are abstract
- interfaces ONLY specify methods
- embedding
- using funcs to customize behavior
- methods can be defined on any type
The Basics
At first structs seem very classic-object (COB) like. A struct has fields and you can define methods on it. The first difference you'll notice though is that the methods are not in the struct.
Packages
It's also important to talk about the role packages play in Go-OO. Anything starting with an uppercase is public, lowercase is private. But unlike COO, privates are package wide.
Interfaces
Interfaces must match
one gotcha is that you may run into - interfaces must exactly match.
Name() fmt.Stringer // does not match Name() someStringStruct
Use a lot
It's ok to use a lot of small interfaces. I have one project that deals with a complex graph with many node types. To keep it under control there are many different node interface types. Specifically, terminal nodes (no output), signals (no inputs), multiplexers (many inputs) and demultiplexers (many outputs) as well as nodes with a UI. And there was a core node type. Now a single node could fulfill several of these interfaces.
Techniques
Staying DRY
Pluggable Method
Put a func field on the struct and have one of the methods wrap a call to that.
Sorter example
Pluggable Interface
Put an interface field on the struct and
Embed Interface
Embed an interface.
Privacy Tricks
Getters and Setters
Go does not have an explicit getter/setter pattern, but they are used frequently to access private fields.
Private abstract
Let's say you'll have 3 structs that will share some similarities, may just as simple as having a read-only ID. You can create a private struct with the necessary fields and embed that in the public structs. Externally, that struct is completely hidden, but the public methods and fields will be exposed.
Constructor Tricks
One of the things I found difficult after I started to understand GOO, was how to handle constructors. If an struct is public, users can bypass your constructor. But if it's not public, it can be very difficult for users to work with.
Constructor Check
Put a private, boolean "constructorOk" field on the object and have the constructor set this to true. Alternately, you can do this with "initilized" and then you don't even need to force the user to call the constructor.
Struct and Interface Pair
Make the struct private and create an interface for it that includes all the public methods. Have the constructor return the interface rather than the struct. This can get a little annoying because you may need to keep casting back. But you can add a private method to the interface that returns the underlying type. Now a user will be unable to implement the interface outside the package and you'll have an easy casting method.