Open/Closed Principle
👑 หัวใจหลักของ Open/Closed Principle (OCP)
Software entities (classes, modules, functions, etc.) should be open for extension but closed for modification.
"การออกแบบซอฟต์แวร์ จะต้องเพิ่มความสามารถใหม่ๆให้ซอฟต์แวร์เราได้ โดยที่ห้ามไปยุ่งกับโค้ดเดิมนะ!" นี่หัวคือใจหลักในเรื่อง OCP ในรอบนี้ แค่อ่านก็กาวแล้ว ถ้าเราจะเพิ่มความสามารถหรือพฤติกรรมใหม่ๆ ปรกติเราก็ต้องแก้โค้ดเดิมนิ แต่นี่เล่นไม่ให้แก้โค้ดเดิมเลย แล้วมันจะทำยังไงกันล่ะ?
❓ ทำไมต้องห้ามแก้โค้ดล่ะ ?
ในการแก้โค้ดเพียง 1 ครั้ง นั่นหมายถึงอาจะเกิด bug ตามมาในโปรแกรมได้ (บางทีแก้ 1 ครั้ง bug อาจะเกิดเป็นสิบๆตัวเลยก็ได้) ดังนั้นเขาเลยบอกว่าโค้ดที่มันเคยใช้งานได้อยู่แล้ว จงอย่าไปยุ่งกับมันปล่อยให้มันทำงานไป ส่วนถ้าอยากได้ความสามารถใหม่ๆจงเขียนโค้ดตัวใหม่เข้าไปเพิ่มซะ
😕 แล้วจะเพิ่มความสามารถใหม่ๆยังไง โดยไม่แก้โค้ดเดิม ?
โดยปรกติเวลาเราเขียนโค้ด เราจะชอบเขียนให้โค้ดมันดิ้นไม่ได้โดยไม่รู้ตัว เช่น กำหนดว่า method นี้จะต้องรับ parameter เป็น Concrete class นี้นะ ตามตัวอย่างด้านล่าง
ปัญหาจากโค้ดตัวอย่าง เราจะไม่สามารถส่ง object อื่นๆเข้าไปทำงานกับ method ReadAllTextFromFile() ได้เลยนอกเสียจาก object ที่มาจาก PdfFile และลูกๆของมันเท่านั้น ดังนั้นทุกครั้งที่เราอยากให้มันอ่านไฟล์แบบใหม่ได้ เราก็ต้องมาแก้โค้ดตรงนี้เสมอๆ แบบนี้ถือว่าละเมิดกฎ OCP
💡 การแก้ให้โค้ดของเราดิ้นได้
แทนที่เราจะไปผูกติด (coupling) โค้ดของเราเข้ากับ Concrete class เราก็แค่เปลี่ยนมาใช้ Abstraction งุยล่ะ
ดังนั้นเราก็แค่เปลี่ยน method ด้านบนให้รับเป็น abstraction ตามโค้ดด้านล่างก็พอแล้ว
จากโค้ดด้านบนจะเห็นว่า เราสามารถส่งคลาสอะไรก็ได้ที่ implement IDocument เข้าไป มันก็จะสามารถทำงานด้วยได้หมดแล้วโดยที่เราไม่ต้องไปแก้ไขโค้ด ReadAllTextFromFile() แม้แต่บรรทัดเดียวเลย นี่แหละพลังแห่งการออกแบบและไม่ผิดกฎ OCP
😒 ควรออกแบบยังไงดี
สมมุติว่าเราต้องเขียนโปรแกรมจัดการไฟล์ PDF โดยที่มีคลาสจัดการไฟล์อยู่ 1 ตัว (DocumentManager) เราจะออกแบบยังไง ?
😟 การออกแบบที่ไม่ดี
ถ้าเราออกแบบให้ตัวจัดการไฟล์มันไปผูกติดอยู่กับ Concrete class เลยนั่นหมายถึง เวลาที่เราจะแก้ไขอะไร เราจะต้องไปแก้ไขเจ้า concrete class ตัวนั่นเท่านั้น นี่คือตัวอย่างการละเมิดกฎ OCP ทำให้ทุกครั้งที่จะเพิ่มไฟล์ประเภทใหม่ๆเข้าไป เช่น Word, Csv, Json ต่างๆ เราจะต้องแก้ไขโค้ดเดิมเสมอ ตามรูปด้านล่าง
😄 การออกแบบที่ควรเป็น
จากที่เราเคยผูกติดกับ Concrete class เราแค่เปลี่ยนมาเป็น Abstraction ซะ เพียงเท่านี้เราก็สามารถเปิดรับการทำงานร่วมกับไฟล์ใหม่ๆในอนาคตได้แล้ว เช่น Word, Csv, Json โดยที่เราไม่ต้องไปแก้ไขโค้ดเดิมเลย
หรือเราจะใช้ Design Pattern 2 ตัวนี้มาช่วยได้นะครับ
🎯 บทสรุป
Open/Closed Principle คือหนึ่งในหัวใจหลักในการออกแบบโค้ดแบบ OOP ซึ่งจะช่วยให้โค้ดเรายืดหยุ่นมากขึ้น reuse ได้และที่สำคัญคือบำรุงรักษาแก้ไขได้ง่ายขึ้นอีกจมเบย ดังนั้นอย่างนิ่งอยู่เฉย จงน้อมรับเอา OCP ไปฉีดเข้าเส้นไปซ๊าาา 🥴
Last updated
Was this helpful?