Skip to content
This repository has been archived by the owner on Feb 8, 2021. It is now read-only.


Repository files navigation


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


2. Designing Classes with a Single Responsibility

  • gear1.go defines a basic Gear with getters
  • gear2.go introduces a new feature (and responsibility)
  • gear3.go hide instance variables (behavior in one place)
  • obscure.go depending on complicated data structures is bad
  • revealing.go isolating the incoming array
  • gear4.go extracting wheel as an internal structure
  • gear5.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 change
  • 5-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.


A Go translation of the example code from Practical Object-Oriented Design in Ruby by Sandi Metz.







No packages published