ในชีวิตการทำงานจริง การพัฒนาออกแบบ Software ระบบหนึ่งขึ้นมา คงไม่ได้มีเพียง File เดียว หรือ Method Main อย่างเดียวแน่ๆ เหมือนตอนที่เรียนอยู่ในมหาวิทยาลัย โดยการทำงานจริงนั้น เราต้องแบบระบบงาน Software ที่ทำอยู่ออกมาเป็น Module หรือ Component ต่างๆ และท้ายที่สุดได้ Class Diagram แต่เมื่อออกแบบเสร็จแล้ว เราจะมั่นใจได้อย่างไรว่า Code ที่เราออกแบบนั้น ไม่มีการทำงานที่ซับซ้อน หรือมีโครงสร้างที่ซับซ้อนมากเกินไป จนทำให้ในอนาคตเมื่อมีการแก้ไข Code นั้นแล้วอาจจะทำให้กระทบไปทั้งระบบ แล้วเราจะมีวิธีจัดการอย่างไงให้สามารถลดความซับซ้อนของระบบได้ ผมขอแนะนำแนวคิด 2C ได้แก่ Cohesion และ Coupling
Cohesion คือ อะไร ?
Cohesion คือ การบอกถึงความสอดคล้องกันของการทำงานในหน่วยใดๆ เช่น ถ้าเรามองในมุมของ Coding ในระดับ Class ความสอดคล้องกันของ Class นั้น หมายถึง Method การทำงานต่างๆที่ควรจะเป็นไปในทางเดียวกัน
เช่น Class ของรถยนต์ ควรมีการทำงานเฉพาะของรถยนต์้เท่านั้น
Class ในการจัดการ Export ไฟล์ Excel(.csv) ต้องความมีการส่วนของการสร้าง File CSV การแปลงข้อมูลชนิดต่างๆ ให้เหมาะสมกับไฟล์ (.CSV) เท่านั้น ไม่ใช่มี Method ในการ Validate เข้ามาเกี่ยวข้อง เป็นต้น
แล้วทำไมเราต้องทำให้เกิดความสอดคล้อง (Cohesion) หละ ?
เพราะ เราต้องการจัดกลุ่มของการทำงานให้เป็นหมวดเดียวกัน ให้อยู่ใน Class เพื่อให้ง่ายต่อการ Maintain และการเพิ่มเติมการทำงานในอนาคต
ลองมองง่ายๆ ถ้า Code Export Excel (.CSV) มันมีการทำงานกระจายไปหมดทุก Module ถ้าเปลี่ยน Requirement ที = งานเข้า
ชนิดของ Cohesion จากแย่ที่สุด ไป ดีที่สุด
- Coincidental Cohesion(แย่ที่สุด): กิจกรรม หรืองานต่างๆ ถูกนำมาจัดกลุ่มรวมกันใน Module โดยไม่มีความสัมพันธ์กันเลย เราอาจจะเรียกว่าเป็น “Utilities” class หรือ Util Class ก็ได้
ตัวอย่าง: Class A ที่ Method สำหรับ Connect DB และ Export File - Logical Cohesion: กิจกรรม หรืองานต่างๆ ถูกนำมาจัดกลุ่มรวมกันใน Module เดียวกัน โดยดูจากปัจจัยอย่างใดอย่างหนึ่ง เช่น Input หรือ Output เป็นต้น แต่ธรรมชาติของการทำงานของมันจะไม่เหมือนกัน
ตัวอย่าง: Class B ที่จัดกลุ่ม Method สำหรับ BackFile และ Export File ไว้ในกลุ่มเดียวกัน เพราะ มีการเขียนไฟล์ออกมาเป็น Output เหมือนกัน - Temporal Cohesion : กิจกรรม หรืองานต่างๆ ถูกนำมาจัดกลุ่มรวมกันใน Module เดียวกัน เนื่องจากเวลาการทำงานเกิดขึ้นพร้อมๆกัน
ตัวอย่าง: Class C จัดกลุ่มสำหรับดึงค่า config, ดึงข้อมูลผู้ใช้ล่าสุด และสร้างที่เก็บ Log File - Procedural Cohesion : กิจกรรม หรืองานต่างๆ ถูกนำมาจัดกลุ่มรวมกันใน Module เดียวกัน เพราะเนื่องจากมีขั้นตอนของการทำงานที่แน่นอน
ตัวอย่าง: Class D จัดกลุ่ม Method สำหรับตรวจสอบสิทธิไฟล์ และ การเปิดไฟล์ มารวมกัน - Communicational/informational cohesion : กิจกรรม หรืองานต่างๆ ถูกนำมาจัดกลุ่มรวมกันใน Module เดียวกัน เพราะมีการจัดการกับข้อมูลตัวเดียวกัน
ตัวอย่าง: Class E จัดกลุ่ม Method InsertStudent, EditStudent, DeleteStudent และ ListStudent รวมกัน เพราะมีการยุ่งกับข้อมูลเดียวกัน คือ ข้อมูลของนักเรียน(Student) - Sequential Cohesion : กิจกรรม หรืองานต่างๆ ใน Module โดย Output ที่ได้จากนั้น อาจจะเป็น Input ของอีกกิจกรรม หรืองาน อื่นๆ
ตัวอย่าง: Class F จัดกลุ่ม Method GetCommissionRate กับ Method GetTotalPrice มารวมกัน เพราะ Method GetTotalPrice ต้องใช้อัตรา Commission จาก Method GetCommissionRate - Functional Cohesion(ดีที่สุด) : กิจกรรม หรืองานต่างๆ ใน Module มีหน้าที่ทำงานเพียงอย่างเดียว
ตัวอย่าง: Class G มีหน้าที่การทำงานอย่างเดียว คือ การ Connect Database
ระบบที่ดีความออกแบบให้มี Cohesion สูง (งานที่เหมือนกัน ควรอยู่ในกลุ่มเดียวกัน)
Coupling คือ อะไร ?
Coupling คือ ระดับความเกี่ยวข้อง หรือ พึ่งพากันของ Module ต่างๆในระบบ ซึ่งระบบที่ดีควรออกแบบให้ Module ต่างๆเป็นอิสระจากกันมากที่สุด ถ้าเรามองในมุม Coding คือ การทำให้ Object ต่างๆ มีการอ้างอิงกันน้อยที่สุด เท่าที่จะเป็นไปได้ เพราะ
- ถ้ามีการเปลี่ยนแปลงโครงสร้างใดๆขึ้นมา ย่อมส่งผลกระทบให้กับ Object อื่นๆ ที่อ้างอิงถึงด้วย หรือ เรียกว่า ripple effect
- เกิดการ Reuse Code ได้ยาก เพราะมี Component ที่เกี่ยวข้องกันเยอะ
- Test Code ได้ยาก เพราะมี Component ที่เกี่ยวข้องกันเยอะ
ตัวอย่าง Class A มีการดึงข้อมูลราคาหุ้นจาก Web Service และ Class B มีหน้าที่ในการหา Market Value ของ Portfolio ถ้า Class A มีการเปลี่ยนแปลง โดยเพิ่ม Parameter เข้าไป จะส่งผลให้ Class B ต้องเพิ่ม Parameter เข้าไปด้วย
ถ้า Object มัน Coupling สูง จะเกิดอะไรขึ้น ลองไปอ่าน YO YO Effect ในการ Coding ดูนะครับ นี่ก็เป็นตัวอย่างนึงของการพัฒนาระบบ OOP ที่ Code มีความพึ่งพากันสูงมากๆ จนเกิดปัญหาครับ
ชนิดของ Coupling จากแย่ที่สุด ไป ดีที่สุด
- Procedural programming
- Pathological couple(Content coupling) Module หนึ่ง เข้าไปแก้ไข Module อีกอันได้ เช่น การเข้าไปแก้ไขตัวแปร
- Global coupling(Common coupling) แชร์ข้อมูล Global ร่วมกัน เช่น UserID ที่ใช้งานอยู่ปัจจบัน
- External coupling : Module แต่ละขึ้นอยู่กับข้อมูลที่มาจากภายนอกระบบ ที่จาก WebService หรือ Text file ที่มี format เฉพาะตัว
- Control coupling ควบคุม flow การทำงานไปยัง Module อื่นๆ
- Stamp coupling (Data-structured coupling) ส่งข้อมูลที่เป็นโครงสร้าง เช่น Object Student
- Data coupling: Module มีการแชร์ Data ร่วมกัน
- Message coupling (low): ความสัมพันธ์ของสอง Module นั้นเกิดจากการเรียกใช้งาน โดยอาจจะมีการส่ง Parameter เข้าไป
- No coupling: ไม่มีความสัมพันธ์ใดๆเลย
- Object-oriented programming(OOP)
- Subclass Coupling : ความสัมพันธ์ระหว่าง SubClass กับ Super Class
ตัวอย่าง: Interface A มีความสัมพันธ์กับ Class B, C และ D - Temporal coupling : ใน Object มีกิจกรรม หรือหน้าที่ในการทำงานตั้งแต่ 2 อย่างเกิดขึ้นพร้อมกัน
ตัวอย่าง: Object E มี Method GetActiveUser กับ GetLastLogin ที่ถูกเรียกใช้งานพร้อมกันทุกๆ 1 วินาที
- Subclass Coupling : ความสัมพันธ์ระหว่าง SubClass กับ Super Class
ทำไมถึงต้องแยกเป็น Coupling ของการพัฒาระบบแบบ OOP กับแบบ Procedural ?
เพราะในการเขียน OOP ยังมีการเขียนโปรแกรมแบบ Procedural ประกอบด้วย เพราะ ถ้าเรายึดหลัก OOP เพียงอย่างเดียว เวลาเขียนโปรแกรมจริงๆคงมี Class จำนวนมหาศาล
ระบบที่ดีความออกแบบให้มี Coupling ต่ำ (พยายามแยกให้ Object ต่างๆเป็นอิสระจากกันมากที่สุด)
วิธีการบอกถึง Cohesion กับ Coupling ?
เราจะประเมิน Cohesion กับ Coupling โดยใช้วิธีการทางสถิติ ซึ่งแสดงความสัมพันธ์ นับ Node ที่เกี่ยวข้องกัน และกำหนดคะแนนขึ้นมาครับ
สรุปสัดส่วนที่ดีระหว่าง 2C มัน คือ เป็นอย่างไร ?
High Cohesion & Low Coupling
High Cohesion & Low Coupling หมายถึง การเขียนโปรแกรมให้มีความสัมพันธ์กันภายใน Class มาให้มากที่สุด และพยายามลดความสัมพันธ์ระหว่าง class ให้น้อยที่สุด โดยที่ class เหล่านั้นควรมีการแบ่งหน้าที่ หรือกิจกรรมกันอย่างชัดเจนครับ
แหล่งข้อมูล