คำจำกัดความ: เอนทิตีซอฟต์แวร์เช่นคลาสโมดูลและฟังก์ชั่นควรเปิดให้ส่วนขยายและปิดการดัดแปลง
ที่มาของปัญหา: ในช่วงวงจรชีวิตของซอฟต์แวร์เมื่อรหัสต้นฉบับของซอฟต์แวร์จำเป็นต้องได้รับการแก้ไขเนื่องจากการเปลี่ยนแปลงการอัพเกรดและการบำรุงรักษาข้อผิดพลาดอาจถูกนำไปใช้ในรหัสเก่าและอาจบังคับให้เราทำการปรับปรุงฟังก์ชั่นทั้งหมดและรหัสดั้งเดิมจะต้องทำการทดสอบซ้ำ
วิธีแก้ปัญหา: เมื่อซอฟต์แวร์จำเป็นต้องเปลี่ยนให้พยายามเปลี่ยนแปลงการเปลี่ยนแปลงโดยขยายพฤติกรรมของเอนทิตีซอฟต์แวร์แทนที่จะแก้ไขรหัสที่มีอยู่
หลักการของการเปิดและปิดเป็นหลักการออกแบบขั้นพื้นฐานที่สุดในการออกแบบเชิงวัตถุซึ่งเป็นแนวทางในการสร้างระบบที่มั่นคงและยืดหยุ่น หลักการของการเปิดและปิดอาจเป็นคำจำกัดความที่คลุมเครือที่สุดของรูปแบบการออกแบบหกประการ มันบอกให้เราเปิดและปิดการดัดแปลง แต่เราจะเปิดและปิดตัวลงได้อย่างไรและไม่บอกเราอย่างชัดเจน ในอดีตถ้ามีคนบอกฉันว่า "คุณต้องปฏิบัติตามหลักการของการเปิดและปิดเมื่อออกแบบ" ฉันจะรู้สึกว่าเขาไม่ได้พูดอะไรเลย แต่ดูเหมือนว่าเขาพูดทุกอย่าง เพราะหลักการของการเปิดและปิดนั้นว่างเปล่าเกินไป
หลังจากคิดอย่างรอบคอบและอ่านบทความมากมายเกี่ยวกับรูปแบบการออกแบบในที่สุดฉันก็มีความเข้าใจเล็กน้อยเกี่ยวกับหลักการของการเปิดและปิด ในความเป็นจริงเราปฏิบัติตามหลักการห้าประการแรกของรูปแบบการออกแบบและจุดประสงค์ของการใช้ 23 รูปแบบการออกแบบคือการปฏิบัติตามหลักการเปิดและปิด กล่าวอีกนัยหนึ่งตราบใดที่เราปฏิบัติตามหลักการห้าประการแรกซอฟต์แวร์ที่ออกแบบมาจะสอดคล้องกับหลักการเปิดและปิด หลักการเปิดและปิดนี้เป็นเหมือน "คะแนนเฉลี่ย" ของระดับของการปฏิบัติตามหลักการห้าประการแรก หากมีการปฏิบัติตามหลักการห้าประการก่อนหน้านี้คะแนนเฉลี่ยจะสูงขึ้นตามธรรมชาติซึ่งหมายความว่าการเปิดการออกแบบซอฟต์แวร์และหลักการปิดมีการปฏิบัติตามอย่างดี หากหลักการห้าประการก่อนหน้านี้ไม่ได้ปฏิบัติตามนั้นหมายความว่าหลักการเปิดและปิดจะไม่ได้ปฏิบัติตาม
ในความเป็นจริงผู้เขียนเชื่อว่าหลักการเปิดและปิดไม่มีอะไรมากไปกว่าการแสดงความหมาย: สร้างกรอบที่มีนามธรรมและขยายรายละเอียดด้วยการดำเนินการ เนื่องจากความยืดหยุ่นและความสามารถในการปรับตัวที่กว้างของสิ่งที่เป็นนามธรรมตราบใดที่นามธรรมนั้นสมเหตุสมผลความเสถียรของสถาปัตยกรรมซอฟต์แวร์สามารถรักษาได้โดยทั่วไป สำหรับรายละเอียดตัวแปรในซอฟต์แวร์เราใช้คลาสการใช้งานที่ได้จากนามธรรมเพื่อขยาย เมื่อซอฟต์แวร์จำเป็นต้องเปลี่ยนเราจะต้องใช้คลาสการใช้งานอีกครั้งตามความต้องการที่จะขยาย แน่นอนว่าสถานที่ตั้งคือสิ่งที่เป็นนามธรรมของเราจะต้องสมเหตุสมผลและเราต้องมองไปข้างหน้าและมองการณ์ไกลในการเปลี่ยนแปลงความต้องการ
ในคำจำกัดความของหลักการเปิดและปิดกิจการซอฟต์แวร์อาจอ้างถึงโมดูลซอฟต์แวร์โครงสร้างท้องถิ่นที่ประกอบด้วยหลายคลาสหรือคลาสอิสระ
ซอฟต์แวร์ใด ๆ จำเป็นต้องเผชิญกับปัญหาที่สำคัญนั่นคือความต้องการของพวกเขาจะเปลี่ยนไปตามกาลเวลา เมื่อระบบซอฟต์แวร์ต้องการเผชิญกับความต้องการใหม่เราควรพยายามอย่างเต็มที่เพื่อให้แน่ใจว่ากรอบการออกแบบระบบมีความเสถียร หากการออกแบบซอฟต์แวร์เป็นไปตามหลักการเปิดและปิดมันจะสะดวกมากในการขยายระบบและไม่จำเป็นต้องปรับเปลี่ยนรหัสที่มีอยู่เมื่อขยายตัวเพื่อให้ระบบซอฟต์แวร์มีเสถียรภาพและความต่อเนื่องที่ดีขึ้นในขณะที่มีความยืดหยุ่นและความยืดหยุ่น เมื่อเครื่องชั่งซอฟต์แวร์มีขนาดใหญ่ขึ้นเรื่อย ๆ อายุการใช้งานซอฟต์แวร์จะยาวนานขึ้นและค่าใช้จ่ายในการบำรุงรักษาซอฟต์แวร์จะสูงขึ้นเรื่อย ๆ และการออกแบบระบบซอฟต์แวร์ที่ตรงกับหลักการเปิดและการปิดนั้นมีความสำคัญมากขึ้นเรื่อย ๆ
เพื่อให้เป็นไปตามหลักการของการเปิดและปิดจำเป็นต้องออกแบบระบบอย่างเป็นนามธรรมและสิ่งที่เป็นนามธรรมเป็นกุญแจสำคัญในหลักการของการเปิดและปิด ในภาษาการเขียนโปรแกรมเช่น Java และ C#สามารถกำหนดเลเยอร์นามธรรมที่ค่อนข้างเสถียรสำหรับระบบและพฤติกรรมการใช้งานที่แตกต่างกันสามารถย้ายไปยังเลเยอร์การใช้งานที่เฉพาะเจาะจงเพื่อให้เสร็จสมบูรณ์ ในภาษาการเขียนโปรแกรมเชิงวัตถุจำนวนมากกลไกเช่นอินเทอร์เฟซและคลาสนามธรรมมีให้ซึ่งสามารถกำหนดชั้นที่เป็นนามธรรมของระบบแล้วขยายผ่านคลาสคอนกรีต หากคุณต้องการปรับเปลี่ยนพฤติกรรมของระบบไม่จำเป็นต้องทำการเปลี่ยนแปลงใด ๆ กับเลเยอร์นามธรรม คุณจะต้องเพิ่มคลาสคอนกรีตใหม่เพื่อใช้ฟังก์ชั่นทางธุรกิจใหม่เพื่อขยายฟังก์ชั่นของระบบโดยไม่ต้องแก้ไขรหัสที่มีอยู่และตรงตามข้อกำหนดของหลักการเปิดและปิด
ระบบ CRM ที่พัฒนาโดยซอฟต์แวร์ Sunny สามารถแสดงแผนภูมิประเภทต่าง ๆ เช่นแผนภูมิวงกลมและแผนภูมิแท่ง เพื่อรองรับวิธีการแสดงแผนภูมิหลายวิธีแผนการออกแบบดั้งเดิมจะแสดงในรูปด้านล่าง:
ตัวอย่างรหัสต่อไปนี้มีอยู่ในวิธีการแสดงผล () ของคลาส Chartdisplay:
...... ถ้า (type.equals ("pie")) {piechart chart = ใหม่ piechart (); chart.display (); } อื่นถ้า (type.equals ("bar")) {barchart chart = new barchart (); chart.display (); - ในรหัสนี้หากคุณต้องการเพิ่มคลาสแผนภูมิใหม่เช่น LineChart คุณต้องปรับเปลี่ยนซอร์สโค้ดของวิธีการแสดงผล () ของคลาส Chartdisplay และเพิ่มตรรกะการตัดสินใหม่ซึ่งละเมิดหลักการของการเปิดและปิด
ระบบได้รับการกำหนดค่าใหม่เพื่อให้สอดคล้องกับหลักการของการเปิดและปิด
ในตัวอย่างนี้เนื่องจากแต่ละคลาสแผนภูมิถูกตั้งโปรแกรมไว้ในวิธีการแสดงผล () ของคลาส ChartDisplay การเพิ่มคลาสแผนภูมิใหม่จะต้องปรับเปลี่ยนซอร์สโค้ด ระบบสามารถ refactored ในวิธีที่เป็นนามธรรมเพื่อที่ว่าเมื่อเพิ่มคลาสแผนภูมิใหม่ไม่จำเป็นต้องแก้ไขซอร์สโค้ดซึ่งเป็นไปตามหลักการของการเปิดและปิด วิธีการเฉพาะมีดังนี้:
(1) เพิ่มคลาสนามธรรมคลาส AbstractChart และใช้คลาสคอนกรีตต่างๆเป็นคลาสย่อยของพวกเขา
(2) คลาส Chartdisplay ถูกตั้งโปรแกรมสำหรับคลาสแผนภูมินามธรรมและไคลเอนต์ตัดสินใจว่าจะใช้แผนภูมิเฉพาะที่จะใช้
โครงสร้างหลังจากการสร้างใหม่แสดงในรูปด้านล่าง:
ในรูปที่ 2 เราแนะนำ AbstractChart คลาสนามธรรมและ Chartdisplay ได้รับการตั้งโปรแกรมไว้สำหรับคลาสแผนภูมินามธรรมและไคลเอนต์ตั้งค่าวัตถุแผนภูมิเฉพาะอินสแตนซ์ผ่านวิธี SetChart () ในวิธีการแสดงผล () ของ Chartdisplay วิธีการแสดงผล () ของวัตถุแผนภูมิถูกเรียกให้แสดงแผนภูมิ หากคุณต้องการเพิ่มแผนภูมิใหม่เช่น Linechart คุณจะต้องใช้ Linechart เป็น subclass ของ AbstractChart และฉีดวัตถุ Linechart ลงใน ChartDisplay บนไคลเอนต์โดยไม่ต้องปรับเปลี่ยนซอร์สโค้ดของไลบรารีคลาสที่มีอยู่
หมายเหตุ: เนื่องจากไฟล์การกำหนดค่าในรูปแบบเช่น XML และคุณสมบัติเป็นไฟล์ข้อความธรรมดาจึงสามารถแก้ไขได้โดยตรงผ่านตัวแก้ไข VI หรือ Notepad โดยไม่ต้องรวบรวมในการพัฒนาซอฟต์แวร์การปรับเปลี่ยนไฟล์การกำหนดค่าโดยทั่วไปจะไม่ถือเป็นการปรับเปลี่ยนรหัสแหล่งที่มาของระบบ หากระบบเกี่ยวข้องกับการแก้ไขไฟล์การกำหนดค่าเมื่อขยายออกไปและรหัส Java ดั้งเดิมหรือรหัส C# ไม่ได้ทำการแก้ไขใด ๆ ระบบสามารถพิจารณาระบบที่สอดคล้องกับหลักการเปิดและปิด