Friday, October 2, 2015

Recap สรุปจาก Practical unit testing (GDC 2014)

ครับ จาก Anti-pattern ทั้ง 4 ตัวที่เขียนไป บล็อกนี้เราจะมาทบทวนดูกันอีกทีว่าการเขียน Unit test ที่ดีควรปฏิบัติ

Respect unit test source code as much as production source code

ก็คือให้เคารพโค้ดใน  unit test เช่นเดียวกันกับโค้ดใน production นะครับ

และอย่าลืมยึดหลัก Good unit test นั่นคือ Readable, Maintainable และ Trustworthy


Write once, read many
พึงระลึกไว้อยู่เสมอว่าโค้ดมันถูกอ่านมากกว่าเขียน


Only one explicit assumption.
 หรือให้มี assertion แค่อันเดียวหรือเป้าหมายเดียวครับ

Minimize implicit assumptions
พยายามลด Implicit assumptions หรือ integration test ใน unit test ลงให้เหลือน้อยที่สุด


หมดแล้วจ้า ยังไงลองเข้าไปดูวีดีโออีกทีนะครับ มีหลายอย่างที่ผมไม่ได้หยิบมาเขียน อาจจะได้อะไรเพิ่มเติมครับ
นอกจากนี้ในส่วนของ description ใน youtube ยังมี link ไปยังหนังสือต่างๆที่แนะนำให้อ่านกันด้วยนะครับ เกี่ยวกับการเขียน test มีประโยชน์มากๆ



สวัสดีครับ

สรุปจาก Practical unit testing (GDC 2014): Wide anti-pattern

มาถึง anti-pattern สุดท้ายกันแล้วครับก็คือ Wide anti-pattern

ก็คือเมื่อเวลาที่เราไปแก้ไขโค้ดแก้บั๊กสักตัวนึงแล้วลองรัน Unit test ดูแล้วก็พบว่า Error บานอีกเช่นเคย

ที่นี้มาดูโค้ดกันหน่อย ดูดีจะเห็นว่า test นี้กำลังทดสองโมดูลที่เชื่อ DraftBehavior แต่ Assertion ดันไปอยู่ที่คลาส BehaviorSystem ซึ่งตัวคลาส BehaviorSystem นั้นก็มี  unit test ของมันอยู่แล้ว ดังนั้นการที่เรามาเรียกใช้คลาสอื่นๆใน unit test นั้นจะถือว่าเป็น implicit assumption ก็คือ ใน test นี้ เราไม่ได้ทดสอบแค่คลาส DraftBehavior เท่านั้น แต่ BehaviorSystem นั้นถูกทดสอบไปด้วย
ดังนั้น test นี้จึงไม่ใช้ Unit test อีกต่อไปละครับ ต้องเรียกว่า Integration test แทน

ซึ่งเราอาจจะสรุปได้ว่า
"Test ที่มี Implicit assumptions มากกว่า 1 อัน ไม่นับว่าเป็น Unit test"


ไม่ได้บอกว่า Integration test ไม่ดีนะครับ แต่ต้องทำให้ถูกที่ ถูกทาง ถูกจังหวะของมัน ไม่อย่างนั้นมันก็จะมาขวางทางเราแบบนี้แหละครับ ซึ่งเกี่ยวกับ Integration test นั้น เดี่ยวจะมาเล่าอีกทีครับ

มาดูกันต่อว่าจะแก้ปัญหานี้อย่างไรดี

ตอนที่เรื่มเขียน test นั้น มันอาจจะมี logic บางอย่างที่ในคลาส BehaviorSystem ซึ่งต้องทำการ setup ให้ถูกต้องเสียก่อนถึงจะให้ผลลัพท์ที่ถูกต้องได้

รู้สึกเหมือนกำลัง implement logic นี้สองที่เลยนะครับ ทั้งในโค้ดจริง ทั้ง test เลย

ทางแก้ที่แนะนำก้คือให้หาสิ่งที่เป็น "รอยต่อ" ระหว่างสองคลาสนี้ แล้วนำเทคนิค Test double และ Inversion of control มาใช้ครับ ในตัวอย่างนี้ก็คือ จริงๆแล้ว DraftBehavior.updateImpl() นั้น ต้องการ Heatmap จาก BehaviorSystem


พอเจอจุดที่เป็นรอยต่อแล้วเราก็ทำการสร้าง MockHeatmap ขึ้นมาครับ กำหนดให้มันเหมือนกับตัวที่คลาส BehaviorSystem จะส่งให้เวลาเรียก DraftBehavior.updatImpl()

ที่นี้ ก็ไม่จำเป็นต้องมีการเรียกใช้ BehaviorSystem ใน unit test ของ DraftBehavior แล้วครับ

สำหรับวิธีการในการหารอยต่อ สำหรับมือใหม่อาจจะหายากสักหน่อย แนะนำให้ลองอ่านหนังสือ Working effectively with legacy code ดูครับ

สรุปอีกที่ Wide anti-pattern ก็คือการที่ unit test มันมีการไปเรียกคนอื่นที่ไม่ใช่สิ่งที่เราสนใจใน unit test อันนี้ ซึ่งทำให้เราตกอยู่ในความเสี่ยง มีโอกาสสูงมากที่เราแก้บั๊กหรือเพิ่มฟีเจอร์ใหม่ๆเข้าไปแล้วจำทำให้ unit test ของเราพังครับ

เดี๋ยวบล็อกหน้ามา Recap ทั้งหมดกันอีกทีนะครับ



Wednesday, September 30, 2015

สรุปจาก Practical unit testing(GDC 2014): DEEP anti-pattern

สวัสดีครับ บล็อกนี้เรามาต่อกันที่ anti-pattern ตัวที่ 3 ก็คือ DEEP anti-pattern

ปัญหาคือเวลามี test ที่ไม่ผ่านแล้ว ดูที่ result แล้วมันดูไม่ออกว่ามันพังอะไร

ส่วนใหญ่ที่มีปัญหานี้เกิดจากการที่ test นั้นมันมี  assertion หลายๆอัน ซึ่งละเมิดหลักการเขียน unit test ที่ควรจะมี explicit assertion เพียงอันเดียว


ซึ่งมันทำให้สื่อสารไม่ชัดเจนว่า test  นี้เราจะทดสอบอะไรกันแน่ แน่นอนว่า ผลกระทบก็คือ แก้ไขยาก ต้องใช้เวลาในการทำความเข้าใจ และทำให้ test นั้นเชื่อถือไม่ได้

ทางแก้ก็คือให้แยะ test case ออกมาให้ชัดเจนไปเลยครับ


ทีนี้ เมื่อมาดูผลของการรัน test ก็จะพบว่าอ่านรู้เรื่องมากขึ้น น่าจะนำมาซึ่งการแก้ไขที่ง่ายขึ้นนะ ดังนั้นเราควรจะลดจำนวน assertion ใน test  ให้เหลือน้อยที่สุดเท่าที่เป็นไปได้นะครับ 

Tuesday, September 29, 2015

สรุปจาก Practical unit testing(GDC 2014): WET anti-pattern

ต่อจากบล็อกที่แล้วนะครับ มาดู anti pattern ลำดับต่อมากัน

WET anti-pattern

มันคืออะไร ลองไปค้นในกู้กิ้ลดูก็เจอ wikipedia อันนี้ครับ


ก็ประมาณว่า WET เนี่ยมันจะย่อมาจาก Write Everything Twice หรือ We Enjoy Typing ก็ได้
แปลลวกๆก็คือ การที่เราชอบพิมอะไรเยอะๆ หลายๆครั้งนั่นเอง (ก็อปวางก็เข้าข่ายนะครับ อิอิ)

ในวีดีโอนั้นยกตัวอย่างว่า เวลาเราแก้ไขโค้ดจริงแล้ว test มันพัง(ซึ่งก็ถูกแล้วนะ) ที่นี้พอไปดูว่า test มันพังตรงไหนก็เจอเพียบเลย อย่างนี้ test มันก็มาขัดขวางการทำงานของเราน่ะสิ!


สาเหตุก็มากจากเจ้า WET นี่เองครับ ลองดูจากตัวอย่างที่เค้ายกมา จะเห็นว่า ใน test มันมีอะไรซ้ำๆกันเยอะเลย

ก็คือใน test  ของเราไม่ได้ยึดหลัก DRY(Don’t Repeat Yourself) เลยนะ!


ดังนั้นจึงควรแก้ไขโดยการ extract  มันออกมาเป็น helper function ซะ


ตรง Assertion ก็เช่นกันควรทำให้มันสื่อสารให้ชัดเจนว่าเราต้องการทดสอบอะไร เพื่อให้ test ของเรามันแก้ไขดูแลรักษาได้ง่าย แนะนำให้สร้าง Custom assert ขึ้นมาเลยครับ


แต่จุดที่ควรจะปล่อยเอาไว้คือ ในส่วนที่เป็น Act ต้องคงไว้ เพราะมันคือสาระสำคัญของ test ของเราครับ



สรุปอีกที่ WET anti-pattern  ก็คือการที่เราปล่อยให้มีโค้ดที่ซ้ำๆกันในเทส แล้วละเลยไม่ได้จัดการอะไรกับโค้ดซ้ำๆเหล่านั้นเลย ซึ่งเราอาจจะทำได้อย่างดีในโค้ดหลัก แต่ไม่ได้ทำในส่วนของ test นำมาซึ่งปัญหาในการแก้ไขในระยะยาว ดังนั้น ถ้าจะเขียน unit test แล้ว ก็ต้องดูแลมันไปพร้อมๆกันทั้งหมดนะครับ ไม่งั้นมันจะกลับมาหลอกหลอนคุณแน่นอน

บล็อกหน้ามาต่อกันที่ DEEP anti pattern ครับ 

สรุปจาก Pratical unit testing(GDC 2014): Opaque anti-pattern.

สวัสดีครับ พอดีเปิดไปเจอวีดีโอน่าสนใจเข้าอันนึงเกี่ยวแนวทางการเขียน unit test จากงาน Game dev conference เมื่อปี 2014 เลยเอามาสรุปเก็บไว้ครับ


ในวีดีโอนั้นจะพูดถึง Anti pattern ในการเขียน unit test 4 แบบด้วยกัน วันนี้เราจะมาเริ่มที่แบบแรกกันก่อน

Opaque anti-pattern

ลองไปเปิดดิกดู Opaque นั้นก็แปลว่า ทึบ, อับแสง, ไม่โปร่งใส่ แล้วมันเกี่ยวอะไรกับการเขียนเทส ลองมาดูกัน

1.Hard to see HOW.

คือโค้ดที่ดูยากว่ามันทำงานอย่างไร มันทำให้ยากต่อการทำความเข้าใจ ดูแลยาก แก้ไขยาก

2.Magic literals

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



3.Informative consistent test name.

ก็คือชื่อ test ที่ไม่ได้สื่อว่า test นั้นจะทดสอบอะไร คาดหวังอะไร ซึ่งในวีดีโอนั้นได้แนะนำรูปแบบการตั้งชื่อ test ตามรูป

4.Arrange-Act-Assert.

test ที่ไม่ได้แบ่งให้เห็นชัดเจนระหว่างสามขั้นตอนนี้ ดังนั้นก็ควรจะแบ่งให้ชัดเจนนะครับ

จบแล้วครับ เดี๋ยวมาต่อตอนหน้า กับ WET anti pattern 



ลองกดดูวีดีโอด้วยนะครับ

Tuesday, May 26, 2015

Estimation จุดเริ่มต้นเส้นทาง Agile ของผม

วันก่อนครับ ในขณะที่ขับรถไปกับเพื่อนสนิทท่านหนึ่งก็ได้คุยกันไปเรื่อยๆ คุยไปคุยมาก็นึกถึงเรื่องที่ทำให้ผมเริ่มสนใจใน Agile ขึ้นมาได้ เลยอยากมาแชร์

นั่นคือเรื่อง Estimation หรือแปลเป็นไทยก็คือการ ประเมิน

ผมมีปัญหากับการประเมินมากๆ รู้สึกแย่สุดๆเวลาที่ต้องประเมินงานสักงานหนึ่ง ต้อบมาตอบคำถามว่า งานนี้ต้องใช้เวลาเท่าไหร่ หรือ บั๊กนี้ต้องใช้เวลาเท่าไหร่ในการแก้ WTF! ผมจะไปตอบได้ยังไง

มีผู้ใหญ่ท่านหนึ่งบอกผมว่าให้ทำบ่อยๆ เดี๋ยวจะประเมินแม่นขึ้นเรื่อยๆเอง

แต่ผมว่า งานแต่ละงาน มันมีรายละเอียดไม่เหมือนกันนะ ผมนึกไม่ออกเลยว่าเราจะประเมินแบบนี้แม่นขึ้นได้ยังไง

เพราะฉะนั้น สิ่งที่ทำได้ก็มีเพียงการเดาเท่านั้นแหละครับ ก็เลือกตัวเลขขึ้นมาสักตัวแล้วก็ลงเวลาไป

ทีนี้ก็จะมีคำถามต่อมาอีกว่า เฮ้ยตัวเลขนี้มาได้ยังไง เยอะไปมั้ย ฯลฯ ต้องมานั่งต่อรองกันอีก เป็นเรื่องที่ผมเหนื่อยหน่ายมาก

ผมจึงเริ่มออกตามหาว่าโลกภายนอกเขาทำกันยังไงนะ หลักการที่ถูกต้องมันคืออะไร ก็เลยได้เจอคลิปวีดีโอในเว็บ Youtube เข้าอันหนึ่ง (ผมหาเท่าไหร่ก็หาไม่เจอ เนื่องจากมันนานมากๆแล้ว เลยไม่สามารถหามาแปะตรงนี้ได้ ขอโทษด้วยครับ -/\-) เป็นการแนะนำ Session ของงานสัมมนางานไหนสักงานหนึ่งนี่แหละ เมื่อประมาณปี 2011-2012
ในคลิปนั้นเป็นลุงหัวเกรียนๆคนหนึ่งออกมาขายของ แกเล่าให้ฟังว่า เวลาเราประเมินว่างานงานหนึ่งมันใหญ่ขนาดไหนนี่เราทำยังไง เราก็กะๆเอาใช้มั้ยครับ แต่เราไม่มีทางรู้ได้หรอกว่ามันใหญ่หรือเล็กจริงๆ

ลองเอาขวดน้ำขวดหนึ่งมาวาง แล้วลองกะดูสิว่าขวดนี้มันใหญ่หรือเล็ก ทำไม่ได้ใช้มั้ยล่ะ

ทีนี้ มันจะดีกว่ามั้ยถ้าเรามีขวดน้ำที่ใหญ่กว่ามาวางคู่กันให้เทียบได้ง่ายๆ อันนี้เป็นการประเมินแบบ Relative เป็นเทคนิคการEstimateอันหนึ่งที่ใช้ใน Agile ครับ

ผมนี่อึ้งไปเลยครับ โคตรจะ make sense มันมีวิธีแบบนี้ในโลกด้วยเหรอวะเนี่ย

หลังจากดูจบ ผมก็ไม่รอช้ารีบหาข้อมูลทันทีว่าตาลุงหัวเกรียนนี่คือใครกัน แล้วก็ได้เข้าร่วมชั้นเรียน Spartan ได้รู้จักกับเหล่าเกรียนส์ SPRINT3R และนั่นก็คือจุดเริ่มต้นเส้นทาง Agile  ของผมครับ

ป.ล.ผมยังตามหาวีดีโอนี้อยู่นะ ใครเจอรบกวนแจ้งเบาะแสด้วย -/\-

Sunday, May 17, 2015

อย่าเพิ่งรีบเก็บโต๊ะตอนกำลังกิน

สวัสดีครับ วันนี้มาฟังพี่ปุ๋ย เจ้าของ somkiat.cc แบ่งปันเรื่องการเขียนบล็อก

มีสิ่งที่ดีเก็บกลับมาใช้ได้หลายอย่าง แต่ที่อยากนำมาแบ่งปันในบทความนี้คือเรื่องวิธีการเขียน

พี่ปุ๋ยแนะนำว่า เขียนให้เสร็จไปก่อนแล้วค่อยกลับมาดูเพื่อแก้ไขมันทีหลัง

สาเหตุสำคัญเลยที่เวลาเรากำลังพยายามเขียนบล็อกแล้วล้มเหลวคือ "เขียนไปแล้วแก้ไป"

พิมพ์ไปสองสามตัว แล้วก็ย้อนกลับมาดู เอ๊ะ มันดูดีมั้ยนะ แก้ตรงนี้หน่อยดีกว่า ประโยคนี้จะโดนคนด่ามั้ย เฮ้ยอันนี้พิมพ์ผิด อ้าวอ่านไม่รู้เรื่อง ฯลฯ  ส่วนใหญ่แล้วจะกลัวไปเองด้วยนะ แล้วก็พิมพ์ๆแก้ๆมันอยู่อย่างนั้น ถ้าโชคดีก็เข็นจนเสร็จได้

แต่ส่วนใหญ่แล้ว ผมจะเลิกเขียน แล้วก็ปล่อยให้มันอยู่สถานะ draft ไปทั้งอย่างนั้น

แน่นอนว่าไอ้ draft พวกเนี้ย เราไม่เคยเอามาเขียนต่อจนมันเสร็จเลย!

ขโมยรูปมาจาก facebook ของพี่ปุ๋ย https://www.facebook.com/photo.php?fbid=10153321436038588&set=a.424501298587.197700.590338587&type=1&permPage=1


เรื่อง draft นี่พี่ปุ๋ยแกแนะนำให้ลบทิ้งไปให้หมดครับ เพราะถ้าคุณทิ้งไว้นาน ก็คงลืมไปหมดแล้วล่ะ ว่าจะเขียนต่อยังไง

ที่ไอ้คำแนะนำที่ว่าให้เขียนๆไปก่อนเนี่ย ก็มีอยู่ใน Online course ของ Coursera เหมือนกันครับ ในชั้่นเรียน Learning how to learn ซึ่งก็มีนักเขียนมือโปรมาแชร์เกี่ยวกับวีธีการเขียนหนังสือเหมือนกัน คำแนะนำก็ประมาณนี้เลย คือ

"Don't clean table while you are dining."

ขออภัย ผมจำประโยคแบบเป๊ะๆไม่ได้ แต่ใจความก็ราวๆนี้แหละ ซึ่งก็เป็นที่มาของชื่อบทความนี้นั่นเองครับ ถ้าสนใจก็ไปลงเรียนกันได้ครับ เป็นชั้นเรียนที่ดีมากๆ เลยครับ แนะนำๆ

คำแนะนำนี้สามารถนำไปปรับใช้กับการเขียนโค้ดได้เหมือนกันนะครับ

ขอยกขั้นตอนของ TDD มาแปะ มีอยู่ว่า


  • Make it work.
  • Make it right.
  • Make it fast.


การเขียนให้เสร็จไปก่อนค่อยกลับมาแก้เนี่ย ก็คือ Make it work หรือสรุปอีกทีก็คือการทีเราเลือกแก้ทีละปัญหานั่นเองครับ

ตรงนี้มีคำอธิบายเพิ่ม +Chokchai Phatharamalai เคยเล่าให้ฟัง ก็คือตอนที่เราเขียนกับตอนที่เราแก้เนี่ย มันใช้สมองคนละซีกกันครับ ตอนเขียนทีแรก เราใช้สมองด้านเหตุผล แต่ตอนที่แก้ไขหรือตกแต่ง ใส่รูป ฯลฯ เราใช้ด้านอารมณ์ ซึ่งตรงนี้สมองของเราจะมีจังหวะของมันครับ เรื่องพวกนี้มีอยู๋ในชั้นเรียน Learning how to learn เช่นกัน

ผมว่าแนวคิดนี้นำไปปรับใช้ได้กับหลายๆอย่างเลยนะครับไม่ใช่แค่การเขียน ลองดูครับผม

Saturday, May 16, 2015

เขียนเทสนี่มันยากจริงๆ

เราไม่ชอบเขียนเทสเพราะอะไรกันนะ



ย้อนกลับไปสมัยผมเริ่มทำงานใหม่ๆ ก็ถูกบอกให้เขียนเทสเหมือนกัน

แต่ไม่มีใครบอกว่าต้องทำยังไง

เลยทำไปแบบงงๆ เขียนโปรแกรมให้มันทำงานได้ก่อนก็แล้วกัน

พองานเสร็จ เราจะมาเขียนเทส ก็พบว่า ทำไมมันยากจังวะ


  • เขียนเทสนี่มันเขียนยังไง ไม่เห็นมีใครมาบอก ในมหาลัยก็ไม่ได้สอน
  • Test case เค้าออกแบบกันยังไง
  • อยากจะเทสแค่หน่อยเดี่ยว ทำไมต้อง setup นู่นนี่นั่นเต็มไปหมด
  • แล้ว UI ล่ะ จะเทสยังไง
  • Database ต้องมา Roll back ทุกครั้งที่รัน unit test เนี่ยนะ !?


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

แล้วก็เลิกเขียนเทสกันไปในที่สุด มีใครมีอาการคล้ายๆผมอย่างนี้บ้างไหมครับ :)



Saturday, May 2, 2015

การต่อ Micro Block กับการเขียนโค้ด

สวัสดีครับ วันนี้ผมได้นำเอาตัวต่อ Micro block (ของก็อป แหะๆ) ที่ซื้อมาดองไว้นานมาแล้ว เอามาต่อเล่นเสียที
โดยในการต่อจะมีเทคนิคอย่างหนึ่งที่ผมค้นพบเอง ซึ่งก็มั่นใจว่าไม่ใช่ผมคนเดียวหรอกที่มีเทคนิคแบบนี้ เอาเป้นว่าผมยังไม่เคยเจอบทความหรืออะไรก็ตามที่แนะนำเทคนิดการต่อลักษณะนี้อย่างจริงจังก็แล้วกันนะ

โอเค กลับมาที่การต่อ Micro block ของผมนี่ ขอเล่าย้อนไปสักเล็กน้อยตอนที่ผมเริ่มซื้อมาต่อกล่องแรก ก็ไม่มีอะไรมาก ก็กางคู่มือความหาชิ้นส่วนจากในกองมาต่อๆ จนเสร็จ
แต่ผมค้นพบว่า การคุ้ยหาชิ้นส่วนมาจากกองนั้นมันเหนื่อยเอามากๆ
ยิ่งถ้าเป็นตัวที่รายละเอียดสูงๆล่ะก็ ยิ่งเหนื่อยมากขึ้นไปอีก -_-'
แถมความแสบของเจ้าตัวต่อจีนแดงนี้อีกอย่างหนึ่งคือ มันให้ชิ้นส่วนมาไม่ครบ!!
ลองคิดดูนะฮะ ว่ามันปวดร้าวแค่ไหน ที่ชิ้นส่วนที่คุณหามาเนิ่นนานน่ะ มันไม่มีอยู่อ่ะ ;_;
นี่อาจจะเป้นสาเหตุของการดองเรื่องต่างๆเอาไว้ของมนุษยชาติก็ได้นะครับ แหะๆๆ

โอเค กลับมาเข้าเรื่อง ที่นี้ตัวต่อๆมาผมก็พยายามแก้ไขปัญหานี้ครับ ด้วยการแบ่งแยกมันออกเป็นกองๆ ตามประเภท และ สี ของมันซะ แบบในรูป

ที่นี้การต่อก็เป็นเรื่องง่ายกว่าเดิมหลายเท่าเลยครับ เราสามารถหาชิ้นส่วนที่เราต้องการได้เร็วมากๆ ชิ้นส่วนไหนมันไม่มีมาให้ ก็หาชิ้นสีอื่นที่เหลือเยอะๆมาแทนได้ง่ายมาก

ที่ว่ามานั้นมันทำให้ผมนึกถึงข้อความนี้ในบทที่ 10 ของหนังสือ  Clean code ของ  Robert C. Martin ครับ

"Do you want your tools organized into toolboxes with many small drawers each containing well-defined and well-labeled components? Or do you want a few drawers that you just toss everything into?"

ลองกลับไปมองดูโค้ดของเรานะครับว่าเราได้จัดการมันดีพอหรือเปล่า มันถูกออกแบบให้อยู่ตามชั้นวางหรือลิ้นชักมีฉลากติดตามหน้าที่ของมันอย่างดี ให้เวลาจะนำมาใช้ก็ทำได้ง่าย หรือมันกองรวมๆกันอยู่เวลาจะหยิบมาใช้ที่นึงต้องใช้เวลาคุ้ยเป็นวันๆ กว่าจะได้ใช้ แล้วกว่าจะทำให้ฟีเจอร์ที่เรากำลังจะทำมันใช้ได้อีกละ บางทีหาไม่เจอละ หรือมันพันกับชิ้นส่วนอื่นยุ่งมากๆ ก็ทำใหม่เลยละกัน โอ... เหนื่อยน่าดูเลยนะครับนั่น

อันนี้เป็นลิงค์ของหนังสือ Clean code ครับ http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882

เออ เอามาโยงกันได้ไงนะ สงสัยผมจะจินตนาการมากไปละ
อ้อ ของแท้เขาเรียกว่า  Nano block  นะครับ ถ้าใครมีทุนทรัพย์ก็ช่วยอุดหนุนเขาหน่อยนะ ผมเองก็มีอยู่บ้างตัวสองตัวครับ อิอิ

Tuesday, March 31, 2015

[Review] คอร์ส Passionate Product Ownership by Jeff Patton

สวัสดีครับ ด้วยการสนับสนุนจากผู้ใหญ่ใจดีท่านหนึ่ง ทำให้ผมได่มีโอกาสได้เข้าเรียนในคอร์สที่ผมใฝ่ฝันมานาน ก็คือคอร์สนี้แหละครับ ผู้เรียนจะได้รับใบประกาศ CSPO (Certified SCRUM Product Owner) โดยอัตโนมัติ (คนสอนบอกว่าขอแค่ survive ให้ครบ2วันก็พอ ไม่ต้องสอบครับ อิอิ)

โอเค มาเริ่มกันเลย เรื่องจากworkshopนี้เป็นส่วนหนึ่งของงาน Agile India 2015 ดังนั้นผู้เรียนส่วนใหญ่จึงเป็นคนอินเดีย มีคนไทยบินมาเรียน2คนถ้วนและฝรั่งอีกจำนวนหนึ่งครับ  มีผู้เข้าเรียนประมาณ 40 คน นั่งได้โต๊ะละ 5 คน ก็ได้มีเพื่อนรวมโต๊ะเป็นชาวอินเดียสองท่านครับ ปัญหาก็คือผมฟังภาษาอังกฤษสำเนียงอินเดียไม่ค่อยออกครับ แต่คนสอน(ต่อไปขอเรียกว่า ลุงJeff นะครับ เพื่อความสะดวก...ของผม อิอิ) ฟังออกแฮะ น่าจะคุ้นเคยกับคนอินเดียเป็นอย่างดี แต่ก็ผ่านมาได้ครับ รู้เรื่องบ้างไม่รู้เรื่องบ้าง เออๆออๆ ตามน้ำไป ฮิฮิ

มาดูทางด้านการเรียนการสอนกันบ้าง ก็จะเป็นการฟังบรรยายสลับกับทำ workshop สั้นๆ ประมาณ 5 นาทีครับ มากับเนื้อหาที่อัดแน่นสุดๆ แต่ด้วยสไตล์การสอนของ  Jeff  นี่ไม่มีเบื่อเลยครับ น่าทึ่งมากๆ

ในคอร์สนี้มีการใช้สไลด์น้อยมากๆครับ ลุงJeff แกก็จะเล่าเนื้อหาไปพร้อมๆกับวาดรูปลงบนกระดาษครับ โดยแกจะมีอุปกรณ์อยู่ตัวหนึ่งไม่รู้มันเรียกอะไรเหมือนกัน ถ่ายเวลาแกวาดนะฮะแล้วฉายขึ้นจอภาพเลย ทำให้คนเรียนนี่สนุกไปกับการเรียนกับเค้ามากครับ ก็วาดตามลุง Jeff ไปนั่นแหละ มันส์ดีครับ ผมนี้สมุดโน้ตหมดเล่มเลย แล้วลุง Jeff แกเป็นคน Utah ครับเราๆท่านๆที่คุ้นเคยกับสำเนียงอเมริกันอยู่แล้วจึงไม่น่าจะมีปัญหาแต่อย่างไร

พูดถึงเนื้อหาที่เรียนกันบ้าง ก็เกี่ยวกับการทำ Software, เรื่องของ Collaboaration แล้วก็เข้าเรื่อง Process แกเอา Paper ของ Waterfall model มากางให้ดูเลยครับ ว่ามันเขียนไว้ตั้งแต่ปี 1970 แล้วนะ ว่าทำแบบนี้แล้วมันจะเจ๊งนะ ในpaperมันมีการevolveไปเรื่อยๆจนสุดท้าย เราจะได้ข้อสรุปว่า Good process is messy
อันนี้เป็นการปูเรื่องเพื่อเข้าสู่ที่มาของ SCRUM ซึ่งผมว่าเป็นการเล่าเรื่อง SCRUM ที่เจ๋งมากๆ หาจากอาจารย์ท่านอื่นไม่ได้แน่นอน (ไม่ได้บอกว่าท่านอื่นสอนไม่ดีนะครับ)

พอจบเรื่อง SCRUM แล้วแกก็เล่าเกี่ยวกับการทำงานของProduct manager หรือ owner ใน SCRUM นั่นเองครับ พูดถึงการทำงานร่วมกันระหว่าง PO, Dev และ UX,BA ฯลฯ ภาพที่ควรเกิดขึ้นนั้นเป็นอย่างไร, งานของ UX นั้นมีอะไรบ้าง, กระบวนการทำ Product discovery, เรื่อง Output กับ Outcome, การทำ Story mapping, การหา MVP, Metric ที่นำมาใช้วัดความสำเร็จของ Product, การทำ Persona, การกำหนด Prioritize Backlog Strategy ฯลฯ  แล้วยังมีดีเทลยิบๆย่อยๆอีกเยอะครับ เขียนไม่หมด

หมดเรื่อง Product discovery แล้วก็กลับมา cover เรื่อง SCRUM กันอีกครั้ง ก็หยิบเรื่อง กิจกรรมต่างๆใน SCRUM มาคุยกัน เช่น Daily standup PO ควรทำอะไร? อันนี้เป็นคำถามปลายเปิด ให้ผู้เรียนหาคำตอบกันเอาเอง แล้วก็เรื่อง Sprint Review ที่ควรแยกกันกับ Stakeholder Review
ต่อด้วย แนวคิดของ Lean startup นำมาช่วยในการออกแบบ Product ,การทำ Prototype แล้วปิดท้ายด้วย Design thinking แล้วก็ตอบคำถามอีกนิดหน่อย ได้ Key takeaway มาเยอะมากๆครับ ถ้ามีแรงจะเอามาเล่าต่อเรื่อยๆนะ

ระหว่างเรียน ก่อนจะไปเบรก ลุงJeff แกจะให้เราเขียน Key takeaway (หรือ A-ha) มาอย่างน้อยหนึ่งอย่างลงใน Post-itไปแปะที่บอร์ดครับ (คอร์สนี้ใช้ Post-it เปลืองมากๆ บริษัท 3M มาเห็นนี่ต้องน้ำตาไหลอ่ะ) ผมชอบเทคนิคนี้มาก เหมือนกับว่าได้ทบทวนไปในตัว น่านำมาใช้ครับ เวลาไปแชร์ความรู้ให้คนอื่นๆ

จบชั้นเรียนด้วยการให้ผู้เรียนทุกคนเลือก Key takeaway ที่ชอบที่สุดมาหนึ่งอัน แล้วก็จบ ก็แยกย้ายกันกลับ (มีบางท่านยังมันส์อยู่ ก็ไปคุยกับ Jeff ต่อครับ ยาวๆไป อิอิ)

อ้อที่สำคัญคือ คอร์สนี้แจกแหลกครับ ทั้ง Handout ที่พิมพ์สีทั้งเล่ม, ตัวอย่างที่ใช้ใน workshop ก็เก็บกลับบ้านไปด้วยได้เลย(ไม่มีใครเก็บไปเลยแฮะ แอบแปลกใจเล็กน้อย) สุดท้ายคือแกแจกหนังสือครับ ใช่ครับ User Story Mapping ของแกนั่นแหละ แถมยังเซ็นชื่อให้ครบทุกคนอีกตะหาก โคตรป๋าอ่ะ

สรุปว่าสุดยอดมากๆครับคอร์สนี้ ไม่ว่าคุณจะเป็นใครที่เกี่ยวข้องกับการทำ Product น่าจะหาโอกาสมาเรียนกันครับ ไม่ต้องทำ SCRUM ก็ได้ ไม่มีอะไรเกี่ยวข้องกับ Agile เลยก็ยังได้ครับ ลองดูๆ ใบ Cert. เป็นแค่ของแถมครับ

Friday, March 13, 2015

Even a single line is worth extracting if it needs explanation.





อ่านเจอประโยคนี้ในหนังสือ Refactoring  ของลุง Martin Fowler

แปลเป็นไทยก็ได้ความว่า

"ต่อให้เป็นโค้ดแค่บรรทัดเดียว แต่ถ้ามันต้องการคำอธิบายเพิ่ม มันก็ควรจะถูก Refactor"

ยกตัวอย่างง่ายๆเช่น ผมมีเงื่อนไข สักอย่างแบบนี้


if (username !== null && email !== null && password === confirmPassword) {
    ...
}

ตอนที่เราเขียนอาจจะไม่เป็นไร แต่เวลาเรากลับมาอ่านล่ะ หรือลองให้เพื่อนอ่านสิ จะยังรู้เรื่องอยู่มั้ยนะ

เราสามารถช่วยโลกใบนี้ได้ ด้วยการ Extract  ออกไปเป็น  Method หรือ  Function แบบนี้


if(isRegistrationFormCompleted()) {
    ...
}

function isRegistrationFormCompleted(){
    return username !== null && email !== null && password === confirmPassword
}

จะเข้าใจเลยว่าเงื่อนไขชุดนี้เอาไว้เช็คว่าฟอร์มใส่ข้อมูลมาครบแล้วหรือยังใช่มั้ยครับ

ทีนี้ดูต่อไปอีกหน่อย ในชุดเงื่อนไขพวกนี้ ยังดูแล้วยุ่งๆนะฮะ ลองแยกเงื่อนไขแต่ละอันออกไปเป็น Function ดูสิ

if(isRegistrationFormCompleted()) {
    ...
}

function isRegistrationFormCompleted(){
    return isUsernameNotNull() && isEmailNotNull() && isComfirmPasswordMatched();
}

function isUsernameNotNull(){
    return username !== null;
}

function isEmailNotNull(){
    return password !== null;
}

function isComfirmPasswordMatched(){
    return password === confirmPassword;
}


สามารถมองออกได้ทันทีเลยว่าแต่ละเงื่อนไขเราจะเช็คอะไร

ผมจะพอเท่านี้แหละ แต่โค้ดนี้ยัง Refactor ต่อไปได้อีกนะครับ เช่นแยกส่วนเงื่อนไขเหล่านี้ออกไปเป็น Class ใหม่, เปลี่ยนเงื่อนไขเป็น Strategy pattern ฯลฯ แล้วจะมาเขียนแนะนำกันเรื่อยๆครับ

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



Tuesday, February 17, 2015

Refactoring กับ Performance


พอดีไปอ่านเจอในหนังสือ Refactoring to patterns เลยอยากมาแชร์ครับ

คือเรามักจะกังวลไปก่อนว่า เวลาเราทำการRefactorให้Functionมันเล็กๆ แล้ว มันเรียกต่อๆกันเยอะๆแล้วมันจะต้องมีปัญหาเรื่องPerformanceตามมา

ด้วยเหตุผลนี้ เราก็เลยไม่ค่อยอยากจะRefactorเป็นFunctionเล็กๆ กัน (หรือแค่ขี้เกียจก็ไม่รู้นะครับ ฮ่าๆๆ)

ซึ่งในความจริงแล้ว มันเป็นอย่างนั้นจริงหรือเปล่านะ

ในหนังสือเขาว่าไว้อย่างนี้ครับ


First, good designers don't prematurely optimize code

Second, chaining together small method calls often costs very little in performance—a fact you can confirm by using a profiler.

Third, if you do happen to experience performance problems, you can often refactor to improve performance without having to give up your small methods.

สรุปแบบง่ายๆ
ข้อแรก อย่าเพิ่งคิดเรื่อง Performance ตั้งแต่แรก
ข้อสอง มันมีผลกับ Performance นิดเดียวเท่านั้นแหละ ไม่เชื่อก็เอา Profiler มาจับดู
ข้อสาม ถ้าถึงเวลาเจอปัญหา Performance จริงๆ มันแก้ไขได้โดยไม่ต้องไปทำอะไรกับ Function เล็กๆเลยนะ ผมว่าแก้ง่ายกว่าเขียน Functionใหญ่ๆ ยุ่งๆอีก

ลองไปหาอ่านกันดูนะครับ