Maintainable Go
Cherie Hsieh
Outline
o Naming
o Declaration Style
o Packages
o Design pattern
o
Naming
func startServer(host string, config *Config)
func startServer(host string, c *Config)
userMap := make(map[string]*User)
users := make(map[string]*User)
func CountFemale(people []Person) int {
c := 0
for i, p := range people {
if p.gender == "F" {
c++
}
}
return c
}
How to make variable names more clear?
Short Names
o Where the types are descriptive, they should be short.
o Where the types are more ambiguous, the names may provide
documentation.
o The greater the distance between a name's declaration and
its uses, the longer the name should be.
- Andrew Google Inc. What‘s in a name?
Short Names
o Single letter for method receivers, loops and branches.
o Single words for parameters and local variables.
o Two words for methods.
Short Names
o ‘i' to index
o ‘w’ to writer
o ‘r’ to reader
o ‘b’ to buffer
o ‘ok’ check if the key exists in the map
Names without their types
usersMap := make(map[string]*User)
users := make(map[string]*User) Preferred
o The name of the variable should describe its contents,
not the type of the contents.
- Dave Cheney. Practical Go
Names
Use a consistent naming style
A good name is it should be predictable
- Dave Cheney. Practical Go
Declaration Style
Declaration Style
var – Declare a variable without initialization
:= - Declare and initialize a variable
var stdnt Student Preferred
stdnt := Student{Name: "Cherie"}
stdnt := Student{}
Declaration Style
o nil Slice and non-nil Slice
var stdnts []Student Preferred
stdnts = make([]Student, 0) // For encoding JSON objects
Packages
Packages
o Do not put all types inside a models folder.
o Avoid package names like base, common, or util.
Its name doesn’t reflect its purpose, only its function in
breaking the import cycle.
Packages
o Avoid mutable package-global state
It is difficult to write unit tests.
May cause bugs in complex projects.
Packages
o Avoid a rigid project structure.
API Design
API Design
o Avoid taking several parameters of the same type.
// Example:
func Extract(source, target, destination string) error {
// Implementation
}
APIs with multiple parameters of the same type are hard to
use correctly. - Dave Cheney
API Design
o Carefully using nil as parameters.
// Bad
func DoSomething(cfg *customConfig) {
if cfg == nil {
// Use default config
}
}
DoSomething(nil)
Design pattern
Functional options
o A common way to apply your configuration
type Configuration struct {
Port int
Addr string
}
func NewServer(config *Configuration) {
//
}
Functional options
func NewServer(opts ...Option) {
cfg := Configuration{
Port: 8080,
Addr: "localhost"
}
// Use option functions to modify your default configuration
for _, opt := range opts {
opt(&cfg)
}
}
func ChangePort(v int) Option {
return func(cfg *Configuration){
cfg.Port = v
}
}
o A better way by using functional options
Functional options
// Example - gRPC
s := grpc.NewServer(grpc.StatsHandler(&ocgrpc.ServerHandler{}))
// Example - MongoDB
client, err := mongo.NewClient(options.Client().ApplyURI(”.."))
Dependency Injection
// Example
func main() {
cfg := GetConfig()
db, err := ConnectDatabase(cfg.URN)
if err != nil {
panic(err)
}
repo := NewPersonRepository(db)
service := NewPersonService(cfg.AccessToken, repo)
server := NewServer(cfg.ListenAddr, service)
server.Run()
}
Dependency Injection
o Choose a good way to manage package dependency
v Framework (Dig)
v Code Generator (Google-Wire)
Hiring!!!
Sr. Software Engineer – IIOT security
o 2-3
o
o
We are looking for an experienced Software Engineer to develop the
backend management server for an industrial IoT security project.
Golang Pro Tips
References
1. Practical Go: Real world advice for writing maintainable Go programs
https://dave.cheney.net/practical-go/presentations/qcon-china.html
2. GopherCon EU 2018: Peter Bourgon - Best Practices for Industrial Programming
https://www.youtube.com/watch?v=PTE4VJIdHPg
3. What's in a name
https://talks.golang.org/2014/names.slide#1
4. Organize your code with Go packages
https://blog.learngoprogramming.com/code-organization-tips-with-packages-d30de0d11f46
5. Idiomatic Go
https://dmitri.shuralyov.com/idiomatic-go

Maintainable go

  • 1.
  • 2.
    Outline o Naming o DeclarationStyle o Packages o Design pattern o
  • 3.
  • 4.
    func startServer(host string,config *Config) func startServer(host string, c *Config) userMap := make(map[string]*User) users := make(map[string]*User) func CountFemale(people []Person) int { c := 0 for i, p := range people { if p.gender == "F" { c++ } } return c } How to make variable names more clear?
  • 5.
    Short Names o Wherethe types are descriptive, they should be short. o Where the types are more ambiguous, the names may provide documentation. o The greater the distance between a name's declaration and its uses, the longer the name should be. - Andrew Google Inc. What‘s in a name?
  • 6.
    Short Names o Singleletter for method receivers, loops and branches. o Single words for parameters and local variables. o Two words for methods.
  • 7.
    Short Names o ‘i'to index o ‘w’ to writer o ‘r’ to reader o ‘b’ to buffer o ‘ok’ check if the key exists in the map
  • 8.
    Names without theirtypes usersMap := make(map[string]*User) users := make(map[string]*User) Preferred o The name of the variable should describe its contents, not the type of the contents. - Dave Cheney. Practical Go
  • 9.
    Names Use a consistentnaming style A good name is it should be predictable - Dave Cheney. Practical Go
  • 10.
  • 11.
    Declaration Style var –Declare a variable without initialization := - Declare and initialize a variable var stdnt Student Preferred stdnt := Student{Name: "Cherie"} stdnt := Student{}
  • 12.
    Declaration Style o nilSlice and non-nil Slice var stdnts []Student Preferred stdnts = make([]Student, 0) // For encoding JSON objects
  • 13.
  • 14.
    Packages o Do notput all types inside a models folder. o Avoid package names like base, common, or util. Its name doesn’t reflect its purpose, only its function in breaking the import cycle.
  • 15.
    Packages o Avoid mutablepackage-global state It is difficult to write unit tests. May cause bugs in complex projects.
  • 16.
    Packages o Avoid arigid project structure.
  • 17.
  • 18.
    API Design o Avoidtaking several parameters of the same type. // Example: func Extract(source, target, destination string) error { // Implementation } APIs with multiple parameters of the same type are hard to use correctly. - Dave Cheney
  • 19.
    API Design o Carefullyusing nil as parameters. // Bad func DoSomething(cfg *customConfig) { if cfg == nil { // Use default config } } DoSomething(nil)
  • 20.
  • 21.
    Functional options o Acommon way to apply your configuration type Configuration struct { Port int Addr string } func NewServer(config *Configuration) { // }
  • 22.
    Functional options func NewServer(opts...Option) { cfg := Configuration{ Port: 8080, Addr: "localhost" } // Use option functions to modify your default configuration for _, opt := range opts { opt(&cfg) } } func ChangePort(v int) Option { return func(cfg *Configuration){ cfg.Port = v } } o A better way by using functional options
  • 23.
    Functional options // Example- gRPC s := grpc.NewServer(grpc.StatsHandler(&ocgrpc.ServerHandler{})) // Example - MongoDB client, err := mongo.NewClient(options.Client().ApplyURI(”.."))
  • 24.
    Dependency Injection // Example funcmain() { cfg := GetConfig() db, err := ConnectDatabase(cfg.URN) if err != nil { panic(err) } repo := NewPersonRepository(db) service := NewPersonService(cfg.AccessToken, repo) server := NewServer(cfg.ListenAddr, service) server.Run() }
  • 25.
    Dependency Injection o Choosea good way to manage package dependency v Framework (Dig) v Code Generator (Google-Wire)
  • 26.
  • 27.
    Sr. Software Engineer– IIOT security o 2-3 o o We are looking for an experienced Software Engineer to develop the backend management server for an industrial IoT security project.
  • 28.
  • 29.
    References 1. Practical Go:Real world advice for writing maintainable Go programs https://dave.cheney.net/practical-go/presentations/qcon-china.html 2. GopherCon EU 2018: Peter Bourgon - Best Practices for Industrial Programming https://www.youtube.com/watch?v=PTE4VJIdHPg 3. What's in a name https://talks.golang.org/2014/names.slide#1 4. Organize your code with Go packages https://blog.learngoprogramming.com/code-organization-tips-with-packages-d30de0d11f46 5. Idiomatic Go https://dmitri.shuralyov.com/idiomatic-go