Go for Classic OO: Difference between revisions
Adamcolton (talk | contribs) Created page with "== Key Difference == * Private is package wide * structs are concrete, interfaces are abstract * interfaces ONLY specify methods * embedding * using funcs to customize behavio..." |
Adamcolton (talk | contribs) No edit summary |
||
| Line 20: | Line 20: | ||
// does not match | // does not match | ||
Name() someStringStruct | 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 == | == Techniques == | ||
| Line 27: | Line 30: | ||
==== Private abstract ==== | ==== 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. | 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. | |||
Revision as of 16:34, 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
Privacy Tricks
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.