Screen Shot 2558-08-02 at 4.30.15 PM
จากหนังสือ Beyond Legacy Code นั้น
ในบทที่ 9 อธิบายเกี่ยวกับ CLEAN code
ซึ่งมีความน่าสนใจมากมาย
ดังนั้นจึงนำมาสรุปไว้นิดหน่อยสิ

ที่มาของ CLEAN code

มาจากหนังสือ Clean Code: A Handbook of Agile Software Craftsmanship
ของคุณ Robert C. Martin (Uncle Bob)
เป็นแนวปฏิบัติที่มีเป้าหมายให้ developer เขียน code ที่มีคุณภาพที่ดีขึ้น
ทั้งเข้าใจง่าย
ทั้งทดสอบได้ง่าย
ทั้งแก้ไขง่าย
ทั้งดูแลรักษาง่าย

โดยในเรื่องคุณภาพของ code นั้นมันอาจจะเป็นสิ่งที่เล็กน้อย
แต่ว่าความเล็กน้อยนี้ มันสร้างความแตกต่างได้อย่างมหาศาล !!

ยิ่งในโลกของ Object-Oriented ด้วยแล้วนั้นยิ่งสำคัญมาก ๆ เช่น

  • แต่ละ object ควรมีหน้าที่การทำงานชัดเจน
  • แต่ละ object ควรมีพฤติกรรมการทำงานที่ชัดเจน
  • แต่ละ object ควรมีการซ่อนการทำงาน หรือการ implementation ไว้ภายใน
  • และอื่น ๆ อีกมากมาย

ซึ่งมันคือที่มาของ CLEAN code
ประกอบไปด้วย

  • C => Cohesive
  • L => Loosely Coupled
  • E => Encapsulated
  • A => Assertive
  • N => Non-Redundant

ดังนั้นเรามาดูรายละเอียดของแต่ละตัวว่าเป็นอย่างไรกันบ้าง ?

1. Cohesive

เป็นสิ่งแรกของ code ที่ดี และ มีคุณภาพที่ดี นั่นคือ
แต่ละส่วนการทำงานควรทำงานเพียงอย่างเดียว (Single Responsibility)
ทั้ง class และ method นะ

ทำให้ code ที่ได้ออกมานั้น เข้าใจง่าย และ ทำงานด้วยง่าย
ที่สำคัญมันช่วยทำให้เราสร้างระบบง่ายอีกด้วย

แต่สิ่งที่น่าแปลกใจ คือ developer มักจะทำในทางตรงข้าม
ซึ่งเรามักจะได้ยินคำว่า God Class/Object
โดยที่ God class นั้นไม่ใช่ว่ามีการทำงานทุกสิ่งอย่างอยู่ในนั้นนะ
แต่แท้จริงแล้วมันคือ class ที่ยากต่อการแก้ไขต่างหากล่ะ !!!

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

คำถาม
สำหรับระบบที่ซับซ้อนขึ้นล่ะ เราจะยังสร้าง code ที่ยังคงคุณสมบัติ Cohesive อยู่ได้ไหม ?
คำตอบ
ได้สิ โดยให้ใช้การ composition เอานะ

2. Loosely Coupled

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

  • แยกกันทำงาน
  • ทดสอบการทำงาน
  • ตรวจสอบการทำงาน
  • การ reuse
  • การ extend หรือ ขยาย

ในส่วนของ indirection นั้นเราสามารถใช้งาน
Abstract class และ Interface มาช่วยได้นะ
และเราสามารถ inject สิ่งที่เราต้องการเข้าไปได้ง่าย

นั่นหมายความว่า
ให้เราสนใจในส่วนของ abstraction มากกว่า implementation จริง ๆ นะ

แต่ว่า code ไม่จำเป็นต้องมีความสัมพันธ์แบบ loose coupling เสมอไปนะ
อาจจะเป็น tight coupling ก็ได้ ขึ้นอยู่กับริบทของระบบงาน

3. Encapsulated

คือซ่อนการ implementation ของการทำงานหนึ่ง ๆ ไว้ซะ
เป็นประโยชน์จากภาษา Object-Oriented เลยนะ

โดย encapsulation มันไม่ได้หมายถึง
การที่ใส่ private ไว้หน้า method และ property เท่านั้น
แต่เรายังทำการซ่อน interface หรืออะไรก็ตามที่เราต้องการ
จากการ implementation หรือวิธีการสร้างสิ่งที่เราต้องการ

การ encapsulation ที่ดี
มันคือการสร้าง และ ออกแบบจากภายนอกสู่ภายใน หรือ (Outside-in)
นั่นคือ เราสนใจ What คือสิ่งที่เราต้องการ
มากกว่า How คือวิธีการสร้างสิ่งที่ต้องการ

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

4. Assertive

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

เป็นแนวปฏิบัติที่พูดถึงกันน้อยมาก ๆ
แต่มันช่วยเราตัดสินใจว่า
เราควรใส่พฤติกรรมการทำงานหนึ่งใน object ใด
และทำให้แต่ละ object มีหน้าที่การทำงานที่ถูกต้องและเหมาะสม

ตัวอย่างเช่น
ถ้าเรามี class Document ทำหน้าที่เป็นตัวแทนของเอกสาร
ทำการจัดรูปแบบของเอกสารแต่ละชนิด

คำถาม
ถ้าเราต้องการพิมพ์เอกสารนี้ออกมาล่ะ จะทำอย่างไร ?
คำตอบ
ง่ายสุด ๆ คือ ก็เพิ่ม method print() ใน class Document ไปเลยสิครับ !!!
หรือบางคนบอกว่า งั้นก็สร้าง class Printer มาเลยสิ
เอายังไงดีล่ะ ?

ถ้าถาม developer เลยเขาก็จะบอกว่า
class Printer สิ ซึ่งมีหน้าที่ควบคุมการพิมพ์เอกสาร

แต่เดี๋ยวก่อนนะ ลองคิดดูหน่อยสิว่า
ใครรู้ว่าเอกสารจะถูกพิมพ์ ?
Document หรือ Printer ที่รู้ ?
Document ใช่หรือไม่ นั่นคือสถานะของการพิมพ์ของแต่ละเอกสาร
แต่ไม่จำเป็นต้องรู้ว่า Printer ทำการพิมพ์อย่างไร
รู้เพียงว่าถ้าจะพิมพ์ออกมาให้ไปเรียกใช้ หรือ ส่งงานไปยัง Printer แทนก็พอ

ดังนั้นแต่ละ object นั้น
ควรที่จะจัดการสถานะของตัวมันเอง
ไม่ควรให้ object อื่น ๆ มาจัดการนะ
ไม่เช่นนั้นนรกแตกแน่นอน …
หรือไม่เช่นนั้นจะเกิดปัญหา หรือ Code smell ที่เรียกว่า Feature Envy ขึ้นมา

5. Non-Redundant

เรื่องสุดท้ายมันก็สำคัญมาก ๆ นั่นคือ อย่าทำซ้ำ
ท่องไว้เลยสัก 3 รอบ ว่า
อย่าทำซ้ำ
อย่าทำซ้ำ
อย่าทำซ้ำ

เราพบว่าถ้ามี code ที่มันซ้ำ ๆ อยู่เป็นจำนวนมาก
ส่งผลให้ค่าใช้จ่ายในการแก้ไข และ ดูแลรักษาสูงมากมาย
เนื่องจากแทนที่จะแก้ไขเพียงที่เดียว ดันต้องไปแก้ไขหลายที่ !!
มันคือปีศาจร้ายของการพัฒนา software กันเลยทีเดียว

ที่น่าแปลกใจคือ developer ส่วนใหญ่ชอบทำซ้ำ !!

ดังนั้น
อะไรที่ทำซ้ำให้สร้างระบบทำงานแบบอัตโนมัติขึ้นมาซะ
อะไรที่ทำซ้ำ ให้ลด ละ เลิก ซะ

แนวปฏิบัติที่ไปในทิศทางเดียวกัน คือ

  • DRY (Don’t Repeat Yourself)
  • Once And Only Once

ปล. เรามักจะพบว่า การหาส่วนที่มันซ้ำกันนั้นยากมาก !!

สุดท้ายแล้ว

“Good code is CLEAN code”

และการเพิ่มคุณภาพของ code วันนี้
เพื่อความเร็วในการพัฒนาสำหรับวันพรุ่งนี้นะ

วันนี้คุณ CLEAN code กันแล้วหรือยังครับ ?