Awesome
go-poodr
A Go translation of the example code from Practical Object-Oriented Design in Ruby by Sandi Metz.
Use the Go Playground or go run
to try these examples, eg:
chapter2> go run gear1.go
1. Object-Oriented Design
(intro)
2. Designing Classes with a Single Responsibility
gear1.go
defines a basic Gear with gettersgear2.go
introduces a new feature (and responsibility)gear3.go
hide instance variables (behavior in one place)obscure.go
depending on complicated data structures is badrevealing.go
isolating the incoming arraygear4.go
extracting wheel as an internal structuregear5.go
a real Wheel with dependency injection
3. Managing Dependencies
1-dependencies.go
Gear knows too much about Wheel (actually a step back from gear5.go)2-duck-type.go
We don't need a Wheel specifically, just an object that responds to Diameter()3-isolate-new.go
Isolate instance creation (if you can't inject the dependency for some reason)4-isolate-messages.go
Isolate external messages that could be vulnerable to change5-map-init.go
Remove argument order dependencies (probably not the best way to accomplish this)- Skipped a factory method to work with an unwieldy constructor (gear-wrapper).
7-reverse-dependencies.go
What if Wheel depends on Gear? (which is more stable?)
4. Creating Flexible Interfaces
(It's all UML! :-)
5. Reducing Costs With Duck Typing
(structural typing in Go)
trip1.go
A Trip that knows it needs the bicycles prepared.trip2.go
Trip preparation becomes more complicated. It knows too much.trip3.go
A Preparer interface, more abstract but easier to extend.
6. Acquiring Behavior Through Inheritance
(which Go doesn't have)
bikes1.go
Starting with a road bike.bikes2.go
We need mountain bikes too. Switching on the type.- Skipped misapplying inheritance.
bikes4.go
Implicit delegation and type embedding instead of subclasses.bikes5.go
Specializing the Spares method.bikes6.go
Use a hook to push responsibilities into the embedded type.
The template method pattern would require a reference to the embedded type, after it is created. Seems like a pattern that shouldn't be attempted in Go.
7. Sharing Role Behavior With Modules
schedule1.go
Scheduling as part of Bicycle, for later extraction.schedule2.go
Extract and delegate to Schedulable.
8. Combining Objects With Composition
- Skipping first transition, which still uses template methods and inheritance.
parts2.go
Bicycle composed of Parts, which is a slice of Part.parts3.go
Rather than a PartsFactory, I use array-style composite literals.
9. Designing Cost-Effective Tests
Use go test
to run these, eg:
chapter9> go test gear1/gear1_check_test.go
Your GOPATH matters for these, as we are importing a separate package for black box testing.
gear1/gear1_test.go
A basic example using Go's built in testing facilities.gear1/gear1_check_test.go
The same code tested with gocheck and a custom matcher.