of Catastrophe Models (i.e. earthquakes, flood…) • Intranet. Not many users. Complex requests • Go backend, Postgres, memcached, React, D3 • Over 30K lines of Go, 4 developers, 3 years
use for organization/convenience. • A package may depend on a sub-package (specialization) • A sub-package may depend on its parent package (polymorphism) • No import cycles allowed
• Use “root” packages for domain types • Sub-packages group dependencies • Resolve dependencies in commands Similar to: Ports and Adapters a.k.a Hexagonal Architecture
language to learn OO. (Better than Smalltalk!) • No inheritance: Methods + Interfaces In Go, interfaces are satisfied implicitly. This makes them quite different from Java/C# interfaces
the abstraction. Rob Pike in Go Proverbs • Well designed interfaces are more likely to be small interfaces; the prevailing idiom is an interface contains only a single method. Dave Cheney SOLID Go Design
Perils() ([]catmod.Peril, error) } func ProcesStuff(lister PerilLister) { } • We don’t need to modify the catmod package • We can test ProcessStuff with a small mock
hierarchies and the taxonomy of types, Go is about composition Rob Pike Less is exponentially more • The simple structure and natural applicability of lists are reflected in functions that are amazingly non-idiosyncratic. In Pascal the plethora of declarable data structures induces a specialization within functions that inhibits and penalizes casual cooperation Alan Perlis in Structure and Interpretation of Computer Programs
Lambdas can express a domain-level concept type kernelFunc func(y1, y2, x float64) float64 • Body of defer blocks • Goroutines • Error flow • Composition: e.g. converting your HTTP handler into a cached handler
your binary, in addition to your “port 80” web server. • Profiling with pprof TCP port • Server and new port for Prometheus metrics • Handle slow web requests in background go-routines (See my talk at dotGo Paris) • Graceful shutdown (go-routine listening on a chan os.Signal for SIGTERM)
90% of the time • But, if I had a penny for every DB Query() parser I’ve written… • Error handling … ?? • See: Errors are values; take advantage of closures • defer can interact strangely with errors • E.g. DB Transaction Commit / Rollback
(cf. C++) • Code reviews are comfortable • If err != nil { … } makes code easy to understand • Concurrency easy enough for a beginner to get right • Excellent standard library. net/http is great! • Wonderful tooling: test coverage, profiling, race detector • Static binaries! • Two genius-level features: • Interfaces satisfied implicitly, plus usage conventions • Takes the pain out of static types
• Package naming conventions: https://blog.golang.org/package-names • Structuring Applications for Growth: https://go-talks.appspot.com/github.com/gophercon/2016-talks/BenJohnson-StructuringApplicationsForGrowth/main.slide#1 • Hexagonal Architecture: http://alistair.cockburn.us/Hexagonal+architecture • Go Proverbs: https://www.youtube.com/watch?v=PAAkCSZUG1c https://go-proverbs.github.io/ • SOLID Go Design: https://dave.cheney.net/2016/08/20/solid-go-design • Error Handling and Go: https://blog.golang.org/error-handling-and-go • Errors are values: https://blog.golang.org/errors-are-values • Handling slow requests in your Go server https://youtu.be/0qKqVSvB1G0