[Recap] GopherConSG 2019 — Clear is better than clever

--

สวัสดีครับทุกท่าน วันนี้ผมจะมาเล่าประสบการณ์ ที่ได้มีโอกาสเข้าร่วมงาน GopherCon 2019 ณ ประเทศสิงค์โปร์ เป็นงานที่แชร์เนื้อหาที่น่าสนใจเกี่ยวกับภาษา Go ไว้มากมายที่จัดขึ้นทุกปี จาก speaker หลากหลายบริษัทชั้นนำของโลก ที่มาแชร์ประสบการณ์ พร้อม keynote เด็ดๆ ในงานนี้

โดยในบทความนี้ผมขอแชร์เนื้อหาสรุป จาก keynote ของ speaker ที่มีชื่อเสียงโด่งดังมากท่านหนึ่ง ในโลกของภาษา Go คือคุณ Dave Cheney กับหัวข้อ “Clear is better than clever” ซึ่งถือได้ว่าเป็น keynote ที่เรียกเสียงฮือฮาได้ดีทีเดียวใน slide แผ่นท้ายๆ

Starting the session!

เริ่มต้นเปิด keynote ทาง Dave Cheney ก็กล่าวต้อนรับก่อนเลยครับด้วยประโยคที่ว่า

we often cite readability as one of Go’s core tenets, I disagree.

ซึ่งได้ทำการอธิบายมุมมอง และ แนวความคิดข้อแตกต่างระหว่าง Readability และ Clarity ว่าทำไมแตกต่างกัน สิ่งที่น่าสนใจ คือ Dave บอกว่า Gopher ควรจะมุ่งมั่นปรับปรุงโค้ดให้มีความชัดเจนของสิ่งที่ทำ และ การสื่อสารที่มีประสิทธิภาพ

การเขียนโค้ด คือ การสื่อสารรูปแบบหนึ่ง

https://twitter.com/davecheney/status/1125288279044120576

การเขียนโค้ด คือ การใช้ communication skill รูปแบบหนึ่ง ความสามารถในการสื่อสารสิ่งที่ทำออกไปยังอย่างมีประสิทธิภาพ ไม่ใช่สนใจแค่ readability เท่านั้น

Software Programming vs Software Engineering

เรามักได้ยินคำนี้บ่อยมากว่า Go ให้ความเป็น Software Engineering ซึ่งก่อนจะขึ้นภาพนี้ ก่อนหน้า Dave ได้พูดถึง “why would I read your code” และเขาก็ได้ตอบคำถามด้วยภาพนี้ครับ

Software Engineering โดยเนื้อความนั้น หมายถึงพวกเรากำลังทำงานร่วมกัน แม้ว่าบางสถานการณ์เราจะไม่ได้นั่งที่ออฟฟิตเดียวกัน อยู่ต่างเมือง ไม่ได้ทำงานที่บริษัทเดียวกัน แต่!…เรากำลังทำงานร่วมกัน ชิ้นเดียวกัน หรือ กำลังทำงานบางสิ่งที่เกี่ยวข้องกัน

ประสบการณ์ดีๆ สามารถลองได้จากการ contribute project open source สักชิ้น

เราอ่านโค้ดของคนอื่น และ ในขณะเดียวกันคนอื่นก็พยายามทำความเข้าใจโค้ดของเรา

Dave ได้กล่าวถึงประโยคของ Russ Cox ที่อธิบาย ความแตกต่างของ Software programming vs Software engineering ไว้ว่า

Software programming คือ พัฒนาระบบงานให้เสร็จตามที่ได้รับมอบหมายให้เสร็จ แล้วก็ส่งมอบให้คนมาดูแลต่อ

แต่ Software Engineering คือ การออกแบบ และ พัฒนาระบบงาน โดยมองถึงการเติบโตของทีม ดูแลต่อไม่ว่าจะมีสถานการณ์อะไรเกิดขึ้น เช่น requirement เปลี่ยนแปลง feature เพิ่ม แก้ไข bug เพราะ นี่คือ ธรรมชาติของ software engineering.

ความเห็นส่วนตัวนะครับ ผมมองว่าเสน่ห์ของ Engineer culture คือ การช่วยกันออกแบบทีม team scaling ว่าจะทำอย่างไรให้ทีมเติบโต ไปพร้อมกับการสรรสร้างซอฟท์แวร์ที่มีคุณภาพ

เคยอ่านโค้ดแล้วอุทานแบบนี้ไหมครับ…

Dave บอกว่า readability เนี่ยมัน คือ subjective นะ หรือ แล้วแต่มุมมองของแต่ละคนเช่น การตั้งชื่อตัวแปร ความยาวของบรรทัดโค้ด การวางตำแหน่งของโค้ด ดังนั้นควรทำ code review guideline เพื่อให้ได้ team style guide

Clarity ≠ Readability

เราใช้เวลาส่วนใหญ่ไปกับการอ่านโค้ด ทำความเข้าใจมัน สิ่งที่ Dave บอกไว้ คือ

เราเขียนโค้ดเพื่อให้คนอ่าน ไม่ใช่แค่ให้ machine เข้าใจ และ ทำตามคำสั่งเท่านั้น

Dave พูดถึง clear code และ simply readable และเริ่มยกตัวอย่างง่ายๆ โดยพูดถึงเรื่อง variable declaration และ variable initialization ไว้ว่า

ใช้ var เมื่อต้องการ declare ตัวแปร แบบ zero value และ จุดที่เรียกใช้นั้น ไม่ห่างจากจุดที่สร้างมาก และใช้ := สำหรับการ declaring + initialising ซึ่งการทำแบบนี้จะค่อนข้างชัดเจน

zero value for slide

Dave ยกตัวอย่างโค้ดง่ายๆ สำหรับการ declaration และ initialising ตัวแปรให้มีความสอดคล้องกัน ถ้ารู้สึกว่ามีบางสิ่งไม่ปกติ หรือ ต้องการให้คนอ่านโค้ดให้ความสนใจเป็นพิเศษ เช่น

Don't
var min int
max := 1000
Do
min, max := 0, 1000

Accept interfaces, return struct

จากตัวอย่างมี Save(f *os.File) เป็น method ของ Document struct สมมุติว่า requirement เปลี่ยนบอกว่าให้ save struct ของ Documentไปยัง cloud หรือ micro services เราต้องมาตามแก้ signature อีกในทุกๆครั้ง ใช่ไหมครับ??! แถมยังกระทบ caller อีกที่เรียกใช้ method นี้

ดังนั้นสิ่งที่ Dave แนะนำ คือ refactor ไปใช้ io.Writer ซึ่งเป็น interface ที่มี singanture ดังนี้

type Writer interface {
Write(p []byte) (n int, err error)
}

เพื่อเป็นการสร้าง abstraction ของ struct w และไม่สนใจ implementation ว่าเป็นอย่างไร สนใจแค่ behavior และ signature ตรงตามที่ตกลงก็พอ

หมายความว่า เราจะ implement logic w method Write()ด้วยโค้ดที่ save ข้อมูลลง cloud หรือ ลง micro services ตามที่เราต้องการได้ โดยที่ signature ยังเหมือนเดิม ขอแค่ w implement interface

Keep to the left

เป็น common mistake ที่หลายๆคนมักจะหลงลืม คือ การทำ happy path on left

ทำไมมันไม่ compile ??!!

รู้สึกไหมว่ามันทำความเข้าใจยาก

Go spec บอกไว้ว่า return value ควรจะอยู่ statement สุดท้ายก่อนจบฟังก์ชัน แต่ประเด็น คือ โค้ดชุดนี้เราสามารถอ่านได้ แต่ไม่เข้าใจว่าทำไม compile ไม่ผ่าน

มีความชัดเจนขึ้นเยอะ

ดังนั้น refactor มันโดยเปลี่ยนไปใช้ switch...case ซึ่งทำให้โค้ดมีความชัดเจนมากขึ้นเลยทีเดียว (อย่าลืมว่าเราใช้เวลาส่วนมากในการอ่านโค้ด เลือกทางที่ชัดเจน และ ตรงตัว)

Productivity

Dave ให้มุมมองเรื่อง productivity เอาไว้ว่า เราใช้เวลาเท่าไหร่สำหรับการอ่านโค้ด ที่ไม่มีความชัดเจน อ่านแล้วไม่เข้าใจ ซึ่งกว่าจะได้เริ่มทำส่วนที่ต้องทำจริงนั้นก็หมดเวลาไปครึ่งวันแล้ว

ลองตั้งข้อสังเกตุว่าช่วงเราเริ่มโปรเจคใหม่นั้น เราส่งมอบงานได้เร็วมาก เพราะ dependency ยังน้อย แต่พอ feature เพิ่มขึ้น ทีมโตขึ้น โค้ดเยอะขึ้น การแก้ของทำได้ลำบาก ไม่มั่นใจ การเพิ่ม feature ทำได้ช้า

ดังนั้นการออกแบบระบบ การออกแบบโค้ด รวมไปถึงโครงสร้างของโปรเจคนั้น ให้นึกอยู่เสมอว่าโค้ดของเรานั้นมีความพร้อมในการเปลี่ยนในอนาคต เช่น มี requirement ใหม่เข้ามา หรือ มีการเปลี่ยนแปลงของระบบ

Dave บอกอีกว่า Go เน้นเรื่อง productivity

โดยตัดส่วนที่ไม่จำเป็นออกไป Go มอบเครื่องมือต่างๆ ที่ช่วยเราตรวจสอบโค้ด golint / จัด format gofmt / testing tool / get dependency tool / build และ อื่นๆ ทำให้เราโฟกัสกับการสร้างของไปเลย และ โฟกัสที่ทีมมากขึ้น

Keynote บางส่วนใน topic

“ถ้า software มันดูแลยาก มันควรเขียนขึ้นใหม่ ไม่แน่พวกเขาอาจจะไปเขียน go…”

ขอยืม Quote แปลเป็นภาษาไทย จาก พี่ยอด Pallat Anchaleechamaikorn มานะครับ :)

สำหรับหัวข้อนี้ ผมว่าสิ่งที่ผมได้ยิน และ สัมผัสได้คือ Go มีมุมมองที่พยายามสร้างของให้ซับซ้อนน้อย ลด layer บางอย่างที่ไม่จำเป็นออกไป ถ้าการที่เราพยายามสร้างของที่มันโครตคูล เจ๋งๆ Clever แต่ในทีมไม่สามารถเข้าใจได้เลย เราอาจต้องกลับไปปรับทักษะการสื่อสารของเราที่อยู่ในรูปแบบโค้ดใหม่แล้วหละ

และ การสร้าง Engineering culture ในทีม ที่เน้นการสื่อสารไอเดียของสิ่งที่เราทำออกมานั่นคือ โค้ดที่เราเขียน ทำอย่างไรให้เพื่อนในทีมอ่านแล้วเข้าใจ มีความชัดเจนของไอเดีย อย่างที่รู้กัน เราเขียนโค้ดเพื่อให้ machine ตีความและไปทำต่อ แต่ก็อย่าลืมว่าการปรับปรุงระบบนั้น คือ software engineer

เพราะฉนั้น เรามาช่วยกันสร้างบรรยากาศในทีมเกิดทักษะการสื่อสารไอเดีย อย่างมีประสิทธิภาพกันครับ

--

--

Teerapong Singthong 👨🏻‍💻
LINE Developers Thailand

Engineering Manager, ex-Solution Engineering Lead at LINE | Tech | Team Building | System Design | Architecture | SWE | Large Scaling System