วันศุกร์ที่ 10 กรกฎาคม พ.ศ. 2563

ปัญหาเบสคลาสแตกง่าย (Fragile Base Class Problem)

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

วันนี้มาเริ่มด้วยเรื่องทางด้าน object-oriented development ที่ผมได้สอนให้นักศึกษาฟังในวิชา  Component-Based Software Development มาหลายปีแล้ว ซึ่งเรื่องนี้เกี่ยวข้องกับคุณสมบัติที่ทำให้ object-oriented development เป็นที่นิยมก็คือคุณสมบัติ  inheritance และ polymorphism นั่นเอง 

โดยคุณสมบัตินี้ถ้าใช้อย่างไม่ระวังมันก็จะเกิดปัญหากับการพัฒนาโปรแกรมได้ และปัญหาหนึ่งที่มากับแนวคิดนี้ก็คือ ปัญหาที่ทำให้คลาสมีความขึ้นต่อกัน ซึ่งก็เป็นที่มาของปัญหา เบสคลาสแตกง่าย  (Fragile Base Class Problem) ซึ่งผมจะขอเรียกสั้น ๆ ว่า FBC

ปัญหา FBC เป็นปัญหาที่เกิดจากคำถามว่า  ถ้ามีการปรับปรุงเบสคลาส ซึ่งจะขอเรียกว่าคลาสแม่ แล้วจำเป็นต้องปรับปรุงดีไรว์คลาส (derived class) ซึ่งจะขอเรียกว่าคลาสลูก ของมันด้วยหรือไม่ ยกตัวอย่างเช่น สมมติ คลาส A เป็นคลาสแม่ มีคลาส B เป็นคลาสลูก และมี คลาส C เป็นลูกของ B อีกทีหนึ่ง สมมติคลาส C เรียกใช้เมท็อดที่อยู่ในคลาส B คราวนี้ลองสมมติต่อว่าถ้าในเวอร์ชันใหม่ของคลาส A กับ B มีการย้ายเมท็อดที่ C เรีกใช้จากคลาส B ขึ้นไปอยู่ในคลาส A  แน่นอนว่าคลาส A กับ B ต้องคอมไพล์ใหม่ แต่เราควรต้องมาคอมไพล์คลาส C ด้วยหรือไม่ ซึ่งคำตอบของคำถามนี้คือไม่ควร แต่ในภาษาเขียนโปรแกรมบางภาษาเราจำเป็นต้องคอมไพล์คลาส C ด้วย 

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

คงเข้าใจปัญหานี้กันแล้วนะครับ โดยสรุปแล้วปัญหา FBC แบ่งเป็น 2 ประเภทคือ
  • Syntatic FBC หรือเรียกอีกอย่างว่า Fragile Binary Interface Problem
  • Sematic FBC  
โดย Syntactic ก็คือไวยากรณ์ ตัวอย่างของคลาส A B C เป็นตัวอย่างของกลุ่มนี้ ส่วน Semantic ก็คือความหมาย ปัญหาของการแก้ไขโค้ดในคลาสแม่แล้ว ทำให้พฤติกรรมของคลาสลูก เปลี่ยนไปเป็นปัญหาในกลุ่มนี้ 

ถึงตรงนี้คงเห็นแล้วนะครับว่าปัญหา FBC แสดงให้เห็นว่าการใช้งาน inheritance และ polymorphism มีปัญหาคือทำให้คลาสขึ้นแก่กัน และจะเป็นปัญหาในการดูแล และบำรุงรักษาซอฟต์แวร์ซึ่งมีขนาดใหญ่ และนี่เป็นเหตุผลหลักเหตุผลหนึ่งที่ทำให้การพัฒนาโปรแกรมแบบคอมโพเนนต์หลีกเลี่ยงที่จะใช้ inheritance กับ polymorphism และมาใช้การประกอบ (compose) เป็นหลัก

สำหรับบล็อกนี้ขอจบแค่นี้นะครับ บล็อกต่อ ๆ ไปจะมาแสดงตัวอย่างของ Syntactic และ Semantic เพื่อให้เห็นภาพชัดเจนขึ้นครับ

ไม่มีความคิดเห็น:

แสดงความคิดเห็น