Upgrade to Pro — share decks privately, control downloads, hide ads and more …

やはり俺の Go アプリケーション設計はまちがっている。 / My Go Application Design Is Wrong, As I Expected

ktr
September 23, 2018

やはり俺の Go アプリケーション設計はまちがっている。 / My Go Application Design Is Wrong, As I Expected

Student Go #1

ktr

September 23, 2018
Tweet

More Decks by ktr

Other Decks in Technology

Transcript

  1. w :FTBOEOP  w $ݴޠΑΓΦϒδΣΫτࢦ޲ͳݴޠ w ΦϒδΣΫτࢦ޲͔Ͳ͏͔͸ਅِ஋Ͱ͸ͳ͍  (P͸ΦϒδΣΫτࢦ޲ݴޠ͔ʁ *1:

    https://golang.org/doc/faq#Is_Go_an_object-oriented_language *2: ΦϒδΣΫτࢦ޲ೖ໳ ୈ 2 ൛ ݪଇɾίϯηϓτ
  2. w l1BDLBHFYYYQSPWJEFT PSJNQMFNFOUT z͔Β
 ࢝·ΔυΩϡϝϯτ ඞ໊ͣࢺ͕ύοέʔδ໊ʹͳΔ w 4IPSU DPODJTF FWPDBUJWF

     w "WPJETUVUUFS w 40-*%ݪଇʹجͮ͘ (Pͷඪ४ύοέʔδͷಛ௃ *1: https://golang.org/doc/effective_go.html?#package-names
  3. type nopCloser struct { io.Reader } func (nopCloser) Close() error

    { return nil } func NopCloser(r io.Reader) io.ReadCloser { return nopCloser{r} }
  4. package cli func Run(cmd string, args []string) { switch cmd

    { case "echo": fmt.Println(strings.Join(args, " ")) case "reverse": reversed := reverse(args) fmt.Println(strings.Join(reversed, " ")) default: fmt.Println("unknown command") } } $ ./app echo foo bar foo bar
  5. package cli type Command interface { Run(args []string) } func

    Run(cmd Command, args []string) { cmd.Run(args) }
  6. package main type echoCommand struct{} func (c *echoCommand) Run(args []string)

    { // logic } type reverseCommand struct{} func (c *reverseCommand) Run(args []string) { // logic }
  7. package main func main() { cmdName := os.Args[1] args :=

    os.Args[2:] var cmd cli.Command switch cmdName { case "echo": cmd = &echoCommand{} case "reverse": cmd = &reverseCommand{} default: // unknown command } cli.Run(cmd, args) }
  8. package cli type CLI struct { Commands map[string]Command } func

    (c *CLI) Run(args []string) error { cmdName := args[0] cmd, ok := c.Commands[cmdName] if !ok { return errors.New("unknown command") } cmd.Run(args[1:]) return nil }
  9. package main func main() { args := os.Args[1:] c :=

    &cli.CLI{} c.Commands = map[string]cli.Command{ “echo": &echoCommand{}, "reverse": &reverseCommand{}, } c.Run(args) }
  10. type Rectangle interface { SetX(x int) SetY(y int) } type

    Square struct { x, y int } func (s *Square) SetX(x int) { s.x, s.y = x, x } func (s *Square) SetY(y int) { s.x, s.y = y, y }
  11. func TestRectangle(t *testing.T) { var r Rectangle = &Square{} expectedX,

    expectedY := 100, 200 r.SetX(100) r.SetY(200) if x := r.GetX(); x != expectedX { t.Errorf("x expected %d, but got %d", expectedX, x) } if y := r.GetY(); y != expectedY { t.Errorf("y expected %d, but got %d", expectedX, y) } }
  12. type ResponseWriter interface { // WriteHeader sends an HTTP response

    header with the provided // status code. // // If WriteHeader is not called explicitly, the first call to Write // will trigger an implicit WriteHeader(http.StatusOK). // Thus explicit calls to WriteHeader are mainly used to // send error codes. // // The provided code must be a valid HTTP 1xx-5xx status code. // Only one header may be written. Go does not currently // support sending user-defined 1xx informational headers, // with the exception of 100-continue response header that the // Server sends automatically when the Request.Body is read. WriteHeader(statusCode int) }
  13. type ResponseWriter interface { // WriteHeader sends an HTTP response

    header with the provided // status code. // // If WriteHeader is not called explicitly, the first call to Write // will trigger an implicit WriteHeader(http.StatusOK). // Thus explicit calls to WriteHeader are mainly used to // send error codes. // // The provided code must be a valid HTTP 1xx-5xx status code. // Only one header may be written. Go does not currently // support sending user-defined 1xx informational headers, // with the exception of 100-continue response header that the // Server sends automatically when the Request.Body is read. WriteHeader(statusCode int) }