ฉันเขียนคำตอบก่อนหน้านี้เกี่ยวกับหลักการ Open-Closed (OCP) และหลักการแทนที่ของ Liskov (LSP)และหลักการทั้งสองนั้นเกี่ยวข้องกันมาก แต่ก็ยังมีแนวคิดที่แตกต่างกับตัวอย่างที่มีการประดิษฐ์ เพราะคำตอบนี้ฉันจะสัมผัส OCP สั้น ๆ และลึกเข้าไปในกรมทรัพย์สินทางปัญญาและสิ่งที่ทำให้ติ๊กนั้น
ให้ลองคุยกันว่า OCP เกี่ยวข้องและแตกต่างอย่างไรกับหลักการการพึ่งพาการพึ่งพา (DIP) โดยอธิบายหลักการต่าง ๆ ก่อนเป็นอันดับแรก
หลักการผกผันของการพึ่งพา
การอ่านหลักการของ OOD ของลุงบ็อบคุณจะพบว่ากรมฯ ระบุสิ่งต่อไปนี้:
ขึ้นอยู่กับ abstractions ไม่ใช่ concretions
เป็นนามธรรมในชวาจะประสบความสำเร็จเพียงกับinterface
และabstract
คำหลักซึ่งหมายความว่าคุณมี "สัญญา" สำหรับนิติบุคคลซอฟต์แวร์ที่มีรหัสที่จะปฏิบัติตาม ภาษาการเขียนโปรแกรมบางภาษาไม่มีเครื่องมืออำนวยความสะดวกในการตั้งค่าพฤติกรรมอย่างชัดเจนเพื่อให้โค้ดปฏิบัติตามดังนั้นบทคัดย่อจะต้องมีการปฏิบัติตามแบบแผนด้วยตนเองมากกว่าการมีคอมไพเลอร์ช่วยให้คุณบังคับใช้สัญญา เช่นใน C ++ คุณมีคลาสที่มีเมธอดเสมือนและภาษาการเขียนโปรแกรมแบบไดนามิกเช่น Javascript คุณต้องตรวจสอบให้แน่ใจว่าคุณใช้วัตถุในลักษณะเดียวกัน (แม้ว่าในกรณีของ Javascript สิ่งนี้ได้ถูกขยายใน TypeScript ที่เพิ่มระบบประเภท ด้วยการเขียนสัญญาที่ตรวจสอบโดยคอมไพเลอร์)
ชื่อนี้รวมถึงคำว่า "การผกผัน" เนื่องจากตามเนื้อผ้า (คุณรู้จักในยุคมืดแบบเก่าของการเขียนโปรแกรม) คุณเขียนโครงสร้างซอฟต์แวร์ที่มีโมดูลระดับสูงขึ้นอยู่กับโมดูลระดับต่ำ เช่นมันทำให้รู้สึกจะมีButtonAtKitchen
ปัจจัยการผลิตการจัดการหาและKitchenLamp1
KitchenLamp2
น่าเสียดายที่ทำให้ซอฟต์แวร์มีความเฉพาะเจาะจงมากกว่าที่ควรจะเป็นและกราฟวัตถุจะมีลักษณะดังนี้:
ดังนั้นเมื่อคุณสร้างซอฟต์แวร์ให้กว้างขึ้นโดยเพิ่ม "สัญญา" สังเกตว่าลูกศรในกราฟวัตถุ "กลับทิศทาง" Button
โคมไฟห้องครัวที่มีตอนนี้ขึ้นอยู่กับ ในคำอื่น ๆ รายละเอียดตอนนี้ขึ้นอยู่กับ abstractions แทนวิธีอื่น ๆ
ดังนั้นเราจึงมีความหมายที่กว้างมากขึ้นของกรมทรัพย์สินทางปัญญารายละเอียดยังอยู่ในบทความเดิมของกรมทรัพย์สินทางปัญญาโดยลุงบ๊อบ
A. โมดูลระดับสูงไม่ควรขึ้นอยู่กับโมดูลระดับต่ำ ทั้งสองควรขึ้นอยู่กับสิ่งที่เป็นนามธรรม B. บทคัดย่อไม่ควรขึ้นอยู่กับรายละเอียด รายละเอียดควรขึ้นอยู่กับ abstractions
หลักการแบบเปิด
ต่อจากหลักการของลุงบ็อบคุณจะพบว่า OCP ระบุสิ่งต่อไปนี้:
คุณควรจะสามารถขยายพฤติกรรมการเรียนโดยไม่ต้องดัดแปลง
ตัวอย่างหนึ่งของการบรรลุเป้าหมายนี้คือการใช้รูปแบบกลยุทธ์ที่Context
ชั้นเรียนถูกปิดเพื่อแก้ไข (เช่นคุณไม่สามารถเปลี่ยนเป็นรหัสภายในได้เลย) แต่ยังเปิดให้มีการขยายผ่านการร่วมมือกันพึ่งพา (เช่นชั้นเรียนกลยุทธ์)
โดยทั่วไปแล้วโมดูลใด ๆ ที่ถูกสร้างขึ้นเพื่อให้สามารถขยายผ่านจุดขยายของมันได้
OCP คล้ายกับ DIP ใช่ไหม
ไม่ไม่ได้จริงๆ
ถึงแม้ว่าพวกเขาทั้งสองกำลังพูดถึง abstractions พวกเขาแตกต่างกันในแนวความคิด หลักการทั้งสองกำลังดูบริบทที่แตกต่างกัน OCP ในโมดูลหนึ่งเดียวและกรมทรัพย์สินทางปัญญาในหลายโมดูล คุณสามารถทำได้ทั้งสองอย่างในเวลาเดียวกันกับรูปแบบการออกแบบ Gang of Four ส่วนใหญ่ แต่คุณยังสามารถหลีกทางให้ห่างจากเส้นทางได้
ในตัวอย่างกรมทรัพย์สินทางปัญญาที่กล่าวถึงข้างต้นด้วยปุ่มและโคมไฟในครัวโคมไฟในครัวจะไม่สามารถขยายได้ (หรือในปัจจุบันไม่มีข้อกำหนดใด ๆ การออกแบบจะหมด OCP แต่ต่อไปนี้กรมทรัพย์สินทางปัญญา
ย้อนกลับ (และ contrived ก) ตัวอย่างจะเป็นโคมไฟห้องครัวจะขยาย (ที่มีจุดส่วนขยายเป็นสิ่งที่ต้องการLampShade
) แต่ปุ่มยังขึ้นอยู่กับโคมไฟ มันถูกหมด แต่กรมทรัพย์สินทางปัญญาดังนี้ OCP
ไม่ต้องกังวลมันเกิดขึ้น
นี่คือสิ่งที่คุณจะเห็นเกิดขึ้นบ่อยครั้งในรหัสการผลิตซึ่งบางส่วนของมันอาจผิดหลักการ ในระบบซอฟต์แวร์ที่มีขนาดใหญ่กว่า (เช่นอะไรที่ใหญ่กว่าตัวอย่างข้างต้น) คุณอาจผิดหลักการหนึ่ง แต่ทำอย่างอื่นตามปกติเพราะคุณต้องทำให้รหัสง่าย นี่คือความคิดของฉันโอเคสำหรับโมดูลขนาดเล็กและในตัวเองเนื่องจากมันอยู่ในบริบทที่เกี่ยวข้องกับหลักการความรับผิดชอบเดี่ยว (SRP)
เมื่อโมดูลบางอย่างมีความซับซ้อนแม้ว่าคุณจะต้องมองมันด้วยหลักการทั้งหมดในใจและออกแบบใหม่หรือปรับโครงสร้างให้เป็นรูปแบบที่รู้จักกันดี