SOLID in Go

16b4817dd82cd0c278ef8719d3d639cf?s=47 syossan27
January 31, 2019

SOLID in Go

16b4817dd82cd0c278ef8719d3d639cf?s=128

syossan27

January 31, 2019
Tweet

Transcript

  1. 40-*%JO(P Go (Un) Conference #5

  2. I’m @syossan27 Golang Beginner
 
 ʕ ◔ϖ◔ʔ < Write simple

    code !
  3. ࠷ۙ࡞ͬͨ΋ͷ

  4. None
  5. SOLIDʁ OOPʹ͓͚Δ̑ͭͷઃܭݪଇ ɾ୯Ұ੹຿ͷݪଇ ɾ։์ด࠯ͷݪଇ ɾϦείϑஔ׵ݪଇ ɾΠϯλʔϑΣʔε෼཭ͷݪଇ ɾґଘੑٯసͷݪଇ

  6. Ref.

  7. ୯Ұ੹຿ͷݪଇ ̍մͷίʔυʢϞδϡʔϧɺΫϥεʣʹରͯ͠ ̍ͭͷมߋཧ༝Λ࣋ͭ͜ͱɻ 㱺 ґଘίʔυʹΑΔ࿈࠯తมߋͷ༧๷

  8. In Go Goʹ͸Ϋϥεͱ͍͏֓೦͕ແ͍ͨΊɺ͜͜Ͱ ͷҰմͷίʔυ͸ύοέʔδͷ֓೦Ͱݴ͍׵ ͑Δ͜ͱ͕ग़དྷΔɻ 㱺ύοέʔδ͕୯Ұͷ੹຿Λ୲͏Α͏ߟྀ͢ Δ

  9. In Go Goʹ͸Ϋϥεͱ͍͏֓೦͕ແ͍ͨΊɺ͜͜Ͱ ͷҰմͷίʔυ͸ύοέʔδͷ֓೦Ͱݴ͍׵ ͑Δ͜ͱ͕ग़དྷΔɻ 㱺ύοέʔδ͕୯Ұͷ੹຿Λ୲͏Α͏ߟྀ͢ Δ 㱺ద੾ͳύοέʔδ໊ͷ໋໊͕ॏཁ

  10. Bad Package name ɾcommon ɾutils ɾprivate etc…

  11. Why bad? ໊લ͔Βͯ͠ଟ͘ͷ੹೚Λഎෛ͍ࠐΜͰ͍Δ ͨΊɺมߋཧ༝Λଟ๊͑͘ࠐΉՄೳੑ͕ߴ͍

  12. Good name ɾnet/http ɾos/exec ɾencoding/json etc…

  13. ։์ด࠯ͷݪଇ ̍մͷίʔυʢϞδϡʔϧɺΫϥεʣ͕ ɾ֦ுʹରͯ͠։์͞Ε͍ͯΔ ɾमਖ਼ʹରͯ͠ด࠯͞Ε͍ͯΔ ঢ়ଶʹͳΔ͜ͱΛ໨ࢦ͢ɻ 㱺 ίʔυมߋແ͠ʹػೳमਖ਼ɾ௥Ճ͕Մೳ

  14. Example package main import "fmt" type Cat struct{} func (c

    Cat) Legs() int { return 4 } func (c Cat) PrintLegs() { fmt.Printf("I have %d legs\n”, c.Legs()) } func main() { var cat Cat cat.PrintLegs() }
  15. Try ৽͘͠6ຊ଍ͷOctCatͷ֓೦͕ඞཁʹͳͬͨ ৔߹ʹͲ͏ରԠ͢Δ͔ʁ

  16. Bad Code type Cat struct { Type int // 0:

    Cat, 1:OctCat } func (c Cat) Legs() int { if c.Type == 0 { return 4 } else { return 5 } } func (c Cat) PrintLegs() { fmt.Printf("I have %d legs\n", c.Legs()) } func main() { cat := Cat{Type: 0} cat.PrintLegs() octCat := Cat{Type: 1} octCat.PrintLegs() }
  17. Why bad? ࠓޙɺOctCatͷΑ͏ʹػೳ௥Ճ͕͋Δ౓ʹ Legs()ʹif-elseͷίʔυमਖ਼͕Ճ͑ΒΕΔɻ 㱺OCPʹҧ൓͍ͯ͠Δ

  18. Good Code - ຒࠐύλʔϯ

  19. e type Cat struct{ Name string } func (c Cat)

    Legs() int { return 4 } func (c Cat) PrintLegs() { fmt.Printf("I have %d legs\n", c.Legs()) } type OctoCat struct{ Cat } func (o OctoCat) Legs() int { return 5 } func (o OctoCat) PrintLegs() { fmt.Printf("I have %d legs\n", o.Legs()) } func main() { var octo OctoCat var cat Cat fmt.Println(cat.Legs()) // “4” cat.PrintLegs() // “I have 4 legs” fmt.Println(octo.Legs()) // “5” octo.PrintLegs() // “I have 5 legs” }
  20. Good Code - ετϥςδʔσβΠϯύλʔϯ

  21. type FelidaeInterface interface { Legs() int PrintLegs() } type Felidae

    struct { Name string FelidaeInterface } type Cat struct{} func (c Cat) Legs() int { return 4 } func (c Cat) PrintLegs() { fmt.Printf("I have %d legs\n", c.Legs()) } type OctoCat struct{} func (o OctoCat) Legs() int { return 5 } func (o OctoCat) PrintLegs() { fmt.Printf("I have %d legs\n", o.Legs()) } func main() { cat := Felidae{FelidaeInterface: Cat{}} octo:= Felidae{FelidaeInterface: OctoCat{}} fmt.Println(cat.Legs()) cat.PrintLegs() fmt.Println(octo.Legs()) octo.PrintLegs() }
  22. Ϧείϑஔ׵ݪଇ ೿ੜΫϥεΛҰ੾ͷมߋແ͠ʹجఈΫϥεʹஔ ͖׵͑ՄೳͰ͋Δ͜ͱΛ໨ࢦ͢ɻ 㱺 ೿ੜΫϥε͸جఈΫϥεͷڍಈΛมߋ͠ͳ͍

  23. In Go ͦ΋ͦ΋”ܧঝ”ͱ͍͏֓೦͕ແ͍ɻ ͦͷ୅Γʹ”ίϯϙδγϣϯ”͕͋Δ͕ɺຒΊࠐ Μͩߏ଄ମΛ׬શʹஔ͖׵͑Δ͜ͱ͕ग़དྷͳ͍ ͨΊɺLSPҧ൓ͱͳΔɻ

  24. type A struct { } func (a A) Test() {

    fmt.Println("Printing A") } type B struct { A } func ImpossibleLiskovSubstitution(a A) { a.Test() } func main() { a := B{} ImpossibleLiskovSubstitution(a) // Aͱͯ͠ৼΔ෣͑ͣɺΤϥʔͱͳΔͨΊLSPҧ൓͍ͯ͠Δ } Bad Code
  25. type A struct { } type tester interface { Test()

    } func (a A) Test() { fmt.Println("Printing A") } type B struct { A } func PossibleLiskovSubstitution(a tester) { a.Test() } func main() { a := B{} PossibleLiskovSubstitution(a) } Good Code
  26. ຒΊࠐΜͩߏ଄ମ(A)ͷৼΔ෣͍ʹରԠ͢Δ interface(tester)Λઃఆ͠ɺinterfaceΛҾ਺ͷܕ ͱ͢Δ͜ͱͰ೿ੜͰ͋ΔຒΊࠐ·Εͨߏ଄ମ(B) Λஔ͖׵͑Մೳͱ͠ɺLSPҧ൓Λճආ͍ͯ͠Δɻ

  27. ґଘੑٯసͷݪଇ ্ҐϞδϡʔϧ͸ԼҐϞδϡʔϧʹґଘͤͣɺ্ Ґ΋ԼҐ΋ந৅ʹґଘ͢΂͖Ͱ͋Δɻ 㱺 ϞδϡʔϧؒΛૄ݁߹ʹ͢Δ

  28. Dave Cheneyᐌ͘

  29. ʮpackageΛద੾ʹ෼͚ɺ interfaceΛ༻͍ͯந৅Λදݱ͢ Ε͹େৎ෉ɻ͋ͱɺpackageߏ ଄͸ͳΔ͚ͨฏୱʹ͠Α͏Ͷɻʯ

  30. ͕࣌ؒ଍Γͣ͜͜·Ͱɾɾɾ

  31. ·ͱΊ Dave CheneyࢯͷʮSOLID Go DesignʯΛಡ Έ·͠ΐ͏ʂʂʂʂʂ

  32. ͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ɻ