refactoring code ทำอย่างไร

refactoring code ทำอย่างไร

ย้อนกลับไปเพียงเล็กน้อย จากบทความที่แล้ว refactoring code คืออะไร นั่นก็คือ การที่จะต้องยึดหลักนั่นคือ

  • อ่านโค้ดแล้วเข้าใจได้ง่าย (สะอาด)
  • แยกเป็นส่วนๆ เพื่อให้ง่ายต่อการแก้ไข
  • มีประสิทธิภาพการทำงานที่ดีขึ้น

การทำให้โค้ดอ่านเข้าใจได้ง่าย

อันนี้ เราจะต้องยึดหลักของการเขียน coding standard ครับ อันเนื่องมาจาก coding standard เค้าจะกำหนดรูปแบบการเขียนโค้ดเอาไว้อย่างชัดเจนเลย ว่าต้องเขียนรูปแบบไหนอย่างไร ทำให้เราสามารถอ่านแล้วเข้าใจได้โดยทันที ไม่ต้องตีความเพิ่มเติม รวมทั้งควรเขียนโค้ดให้ ถูกต้องตาม syntax ของภาษาที่เราใช้งานอยู่ให้มากที่สุด เพื่อไม่ให้เกิด bug ที่เราตีความ syntax ผิดไปเอง โดยเฉพาะ operation ที่ซับซ้อนมากๆ ต้องทำหลายๆอย่าง หากเป็นไปได้ ไม่ควรเขียนในบรรทัดเดียวจบ แต่ควรแยกการ operation แต่ละส่วนออกมาเป็นคนละบรรทัด เพื่อให้การตีความ operation นั้นไม่ผิดพลาดครับ

ในหัวข้อนี้ เค้ามีการแนะนำกันว่า เราควรแบ่งโค้ดออกมาเป็น ส่วนๆ (block) โดยแต่ละส่วน เป็นการทำงานอย่างใดอย่างหนึ่งโดยเจาะจงเป็นส่วนย่อยๆ และแต่ละส่วน ควรมีโค้ดที่ยาวไม่เกิน 20-25 บรรทัด แต่อย่างไรก็ดีหากเป็นส่วนที่ยุ่งยากมากๆ และซับซ้อนสูงๆ รวมทั้งยังทำงานต่อเนื่อง และผูกพันกันมาก อาจจะยาวได้ถึง 50 บรรทัดก็ยังพอไหวครับ ข้อนี้เป็นสิ่งที่ programmer มักไม่ค่อยทำกัน เพราะคิดว่ามันเสียเวลาในการต้องมาแบ่งงานเป็นส่วนย่อยๆ ในเมื่อมันก็ทำงานต่อเนื่องกันอยู่แล้ว ทำไมต้องแบ่งเป็นส่วนย่อยๆอีก อันนี้ มันมีเหตุผลตรงที่ว่า ความสวยงาม ในการตีความเลยครับ อีกทั้ง เรายังสามารถ debug แยกเป็นส่วนๆได้อีกด้วย ว่าส่วนไหนทำงานผิดพลาดอย่างไรบ้าง ยกตัวอย่าง เราเขียนโค้ด การคำนวน ระยะทาง และ เวลาที่ใช้ในการเดินทาง จากจุดหนึ่งไปอีกจุดหนึ่งซึ่งมันจะต้องประกอบส่วน ส่วนโค้ดที่คำนวนระยะทาง และส่วนโค้ดที่คำนวน เวลา programmer โดยทั่วไป ก็จะเขียนพรืดยาว มาในไฟล์เดียว หรือ function เดียวกันหมด แต่ที่ถูกต้องควรเขียน function หลัก คือ การทำงานของส่วนนี้ และ มี function ย่อยอีกสองอันคือ อันนึงไว้คำนวนระยะทาง อีกอันเอาไว้คำนวนเวลา แล้วเอาผลลัพท์ส่งกลับคืน function หลักครับ

แยกโค้ดเป็นส่วน เพื่อให้ง่ายต่อการแก้ไข

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

ทั้งนี้ ขอให้พิจารณาการแยกส่วนออกมาให้ดี เพราะว่า บางครั้ง การแยกส่วน มันอาจจะเพิ่มความสับสนเพิ่มขึ้นก็ได้ อีกทั้ง การแยกส่วนออกมา ต้องระวังการเกี่ยวพันกันให้มาก (dependency) เช่นว่า เราแยกระบบการทำงานออกมาเป็น 4 ส่วน ส่วนที่ 1 ต้องส่งค่าให้ส่วนที่ 2 ส่วนที่สอง ส่งค่าให้ส่วนที่ 3 ส่วนที่ 3 ส่งค่าให้ส่วนที่ 4 รวมทั้ง ต้องใช้ค่าจากส่วนที่ 1 มาด้วย นี่ต้องระวังเลย เพราะว่า หากว่าส่วนที่ 1 เกิดทำงานเพี้ยน หรือการปรับปรุงการทำงาน ทำให้ผลลัพท์จากส่วนที่ 1 ผิดประเภทไป เช่น จาก string เป็น array มันก็จะ effect เป็นลูกโซ่ต่อไปในทันที ดังนั้นต้องระวังเรื่องนี้ แต่ ไม่ได้ห้าม ว่าไม่ให้มันเกี่ยวพันกันเลย เพราะว่ายังไงก็เป็นไปไม่ได้อยู่แล้ว บางครั้ง การทำให้มันอิสระต่อกันมากๆ มันอาจจะทำให้เปลืองทรัพยากรโดยเปล่าประโยชน์ก็เป็นได้

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

ต้องคำนึงถึงประสิทธิภาพ หรือการทำให้ประสิทธิภาพนั้นดีขึ้น

เท่าที่ผมสังเกตุ คนที่เขียนโค้ดโดยไม่คำนึงถึงประสิทธิภาพการทำงาน มักจะเป็น programmer หน้าใหม่ถึงกลางๆ ที่ยังมีชั่วโมงการบินต่ำๆ แต่ผมเคยเจอ programmer ที่ชั่วโมงบินสูง แต่เขียนโค้ดไม่ได้ใส่ใจเรื่องประสิทธิภาพก็มีเหมือนกันนะครับ (แอบเพลีย และนึกในใจว่า น่าจะเป็นเพราะว่าเค้าไม่ค่อยได้พัฒนาตัวเองเท่าไร) เหตุผลที่เราต้องคำนึงถึงประสิทธิภาพ เพราะว่า เว็บ ที่มีการเปิดใช้งานจำนวนสูงมากๆ คือวันนึงเป็นแสนๆครั้ง บางเว็บ เขียนโค้ดไม่ดีเครื่องทำงานหนัก มันอาจะล่มไปตั้งแต่หลักหมื่นแล้วก็เป็นได้ และการขยาย hardware นั่นก็คือเงินนะครับ บ่อยครั้งครับ ที่โค้ดเดิม เปิดพันคนแล้ว ล่มเอา ล่มเอา แต่พอถูกปรับแก้ไข tune อย่างดีแล้ว ในเว็บเดิม เครื่อง server เดิม พบว่า เปิดเป็นหมื่นคนเครื่องยังสบายๆเลย ก็มีเยอะไป ทั้งนี้เพราะว่าความไม่ใส่ใจในตอนที่เขียน ดังนั้นกระบวนการ refactoring code จะเป็นขั้นตอนที่ให้เราได้ทบทวนถึงสิ่งต่างๆที่ผ่านเลยไป ว่ามันทำงานได้เร็วมากน้อยแค่ไหน ตรงไหนที่ optimize มันได้ก็ทำซะ ซึ่งแน่นอนว่า ต้องใช้ความสามารถ และความรู้ ในการมองให้ออกว่า ทำงานแบบไหนเร็วกว่ากัน เพราะว่า การนั่งรถ BTS ไป 5 สถานี การขึ้นสถานีแรก ลงสถานี ที่ 5 กับการขึ้น 1 ไปลง 2 แล้วขึ้น 2 ไปลง 3 ไปเรื่อยๆ จนถึง 5 มันก็ถึงสถานีสุดท้ายเหมือนกัน แต่ใช้เวลาและพลังงานไม่เท่ากัน

การทำเว็บ ก็เช่นกัน พยายามลดขนาดของไฟล์ถ้าเป็นไปได้ เช่นพวก CSS ก็เอาไปบีบอัดซะ (css optimize) หรือ รูปภาพก็ทำ CSS sprite ซะ บางครั้ง การ optimize เหล่านี้ ทำให้หน้าเว็บ มีขนาดเล็กลงจากเดิม  เพียง 256KB แต่ถ้าเปิด 1 ล้านครั้งนั่นคือ ประหยัด bandwidth ไปได้ 256 GB แล้วครับ เช่นกันกับการคำนวนส่วนต่างๆของระบบ หากเราทำให้ประสิทธิภาพดีขึ้นเพียงเล็กน้อย แต่ด้วยการทำงานเป็นล้านๆครั้ง มันเป็นผลมากครับ

และสำหรับใครหลายคนที่เขียน query ด้วย select * from table; ก็ขอให้เลิกนะครับ พยายาม select เอาขึ้นมาแต่สิ่งที่ตัวเองใช้ก็พอ เพราะว่าถ้าเรามีแค่ 1 พันหรือ 1 หมื่น record ยังไม่เท่าไร แต่ถ้ามันมีเป็นล้านๆ รับรอง มีปัญหาแน่นอนครับ

สรุปท้าย ก็อย่างที่เคยเล่าไปในบทความที่แล้ว refactoring code คืออะไร ก็คือ การทำ refactoring code นั้น เป็นทั้งศาสตร์และ ศิลป์แต่มันเน้นทาง ศิลป์ ซะมากกว่า เพราะมันต้องมองให้ออกก่อน ว่าเขียนแบบไหนถึงจะสวยงาม ถึงจะดูง่าย และการเชื่อมโยงต่างๆ มีความสัมพันธ์กันแบบไหนอย่างไร และพอเมื่อเราจะเริ่มลงมือทำ เราก็อาศัยศาสตร์ที่มี เข้ามาปรับปรุงมัน เช่น ทำให้เขียนโค้ดได้เร็วขึ้น ปรับปรุงการทำงาน ให้ถูกต้องมากขึ้น (เพื่อไม่ให้เกิด bug) เหล่านี้ครับ

สำหรับการทำ refactoring code นั้น เป็นส่วนหนึ่งของกระบวนการ extreme programming ด้วย ซึงถ้ามีโอกาสก็จะมาเล่าให้ฟังกันต่อไปครับ

Create: Modify : 2013-06-16 23:49:48 Read : 6426 URL :