หลักการการเปลี่ยนโครงสร้างและเปิด / ปิด


12

ฉันเพิ่งอ่านเว็บไซต์เกี่ยวกับการพัฒนาโค้ดที่สะอาด (ฉันไม่ได้ใส่ลิงค์ไว้ที่นี่เพราะไม่ใช่ภาษาอังกฤษ)

หนึ่งในหลักการที่โฆษณาโดยไซต์นี้คือหลักการเปิดปิด : ส่วนประกอบซอฟต์แวร์แต่ละรายการควรเปิดเพื่อขยายและปิดเพื่อการปรับเปลี่ยน เช่นเมื่อเรานำไปใช้และทดสอบคลาสเราควรแก้ไขเพื่อแก้ไขข้อบกพร่องหรือเพื่อเพิ่มฟังก์ชั่นใหม่ (เช่นวิธีการใหม่ที่ไม่มีผลต่อคลาสที่มีอยู่) ไม่ควรเปลี่ยนฟังก์ชันการทำงานและการใช้งานที่มีอยู่

ผมปกติใช้หลักการนี้ด้วยการกำหนดอินเตอร์เฟซและระดับการดำเนินงานที่สอดคล้องกันI Aเมื่อชั้นเรียนAมีเสถียรภาพ (ดำเนินการและทดสอบ) ปกติแล้วฉันจะไม่แก้ไขมากเกินไป (อาจไม่เลย) เช่น

  1. หากข้อกำหนดใหม่มาถึง (เช่นประสิทธิภาพหรือการใช้อินเทอร์เฟซใหม่ทั้งหมด) ที่ต้องมีการเปลี่ยนแปลงโค้ดอย่างมากฉันจะเขียนการใช้งานใหม่Bและใช้ต่อไปAตราบเท่าที่Bยังไม่ครบกำหนด เมื่อBครบกำหนดแล้วสิ่งที่จำเป็นต้องมีก็คือเปลี่ยนวิธีการIสร้างอินสแตนซ์
  2. หากความต้องการใหม่แนะนำการเปลี่ยนแปลงอินเตอร์เฟซเป็นอย่างดีฉันกำหนดอินเตอร์เฟซใหม่และการดำเนินงานใหม่I' A'ดังนั้นI, Aมีแช่แข็งและยังคงอยู่ในการดำเนินการสำหรับระบบการผลิตเป็นเวลานานเป็นI'และA'มีไม่เพียงพอที่มั่นคงเพื่อแทนที่พวกเขา

ดังนั้นในมุมมองของการสังเกตเหล่านี้ฉันรู้สึกประหลาดใจเล็กน้อยที่หน้าเว็บนั้นแนะนำให้ใช้การปรับโครงสร้างที่ซับซ้อน "... เนื่องจากไม่สามารถเขียนโค้ดโดยตรงในรูปแบบสุดท้าย"

ไม่มีความขัดแย้ง / ความขัดแย้งระหว่างการบังคับใช้หลักการเปิด / ปิดและแนะนำให้ใช้การปรับโครงสร้างที่ซับซ้อนเป็นวิธีปฏิบัติที่ดีที่สุดหรือไม่? หรือความคิดในที่นี้คือเราสามารถใช้ refactorings ที่ซับซ้อนในระหว่างการพัฒนาคลาสAแต่เมื่อคลาสนั้นได้รับการทดสอบสำเร็จแล้วควรจะถูกแช่แข็งหรือไม่

คำตอบ:


9

ผมคิดว่าหลักการเปิดปิดเป็นเป้าหมายการออกแบบ หากคุณต้องละเมิดมันนั่นหมายความว่าการออกแบบเริ่มต้นของคุณล้มเหลวซึ่งเป็นไปได้อย่างแน่นอนและเป็นไปได้

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

คุณอาจกำลังทำการปรับโครงสร้างใหม่เพื่อให้สามารถใช้งานฟีเจอร์ต่อไปของคุณได้โดยไม่ละเมิด OCP เมื่อคุณดำเนินการ


แน่นอนคุณไม่ควรคิดเป็นหลักการใด ๆ ที่เป็นการออกแบบเป้าหมาย พวกเขาเป็นเครื่องมือ - คุณไม่ได้ทำให้ซอฟต์แวร์สวยและถูกต้องตามหลักเหตุผลเกี่ยวกับอวัยวะภายในคุณกำลังพยายามสร้างคุณค่าให้กับลูกค้าของคุณ มันเป็นแนวทางไม่มีอะไรเพิ่มเติม
ต. Sar

@ T.Sar หลักการเป็นแนวทางสิ่งที่คุณมุ่งมั่นพวกเขาจะมุ่งเน้นไปที่การบำรุงรักษาและปรับขนาดได้ ดูเหมือนว่าเป้าหมายการออกแบบสำหรับฉัน ฉันไม่เห็นหลักการเป็นเครื่องมือในวิธีที่ฉันเห็นรูปแบบการออกแบบหรือกรอบงานเป็นเครื่องมือ
Tulains Córdova

@ TulainsCórdovaการบำรุงรักษาประสิทธิภาพความถูกต้องความสามารถในการปรับขนาด - นั่นคือเป้าหมาย หลักการแบบเปิดเป็นวิธีที่มีผลต่อพวกเขา - เพียงหนึ่งในหลาย ๆ คุณไม่จำเป็นต้องผลักดันบางอย่างไปสู่หลักการแบบเปิดหากไม่สามารถทำได้หรือมันจะเบี่ยงเบนจากเป้าหมายที่แท้จริงของโครงการ คุณไม่ได้ขาย "Open-closedness" ให้กับลูกค้า ในฐานะที่เป็นแนวทางเพียงอย่างเดียวก็ไม่ดีไปกว่ากฎง่ายๆที่สามารถยกเลิกได้หากคุณค้นหาวิธีที่จะทำสิ่งต่างๆของคุณในแบบที่อ่านได้และชัดเจนยิ่งขึ้น แนวทางเป็นเครื่องมือหลังจากทั้งหมดไม่มีอะไรเพิ่มเติม
T. Sar

@ T.Sar มีหลายสิ่งที่คุณไม่สามารถขายให้กับลูกค้าได้ ... ในทางกลับกันฉันเห็นด้วยกับคุณในสิ่งนั้นจะต้องไม่ทำในสิ่งที่เบี่ยงเบนจากเป้าหมายของโครงการ
Tulains Córdova

9

หลักการ Open-Closed เป็นตัวบ่งชี้ว่าซอฟต์แวร์ของคุณออกแบบมาได้ดีเพียงใด ไม่ใช่หลักการที่จะทำตามอย่างแท้จริง นอกจากนี้ยังเป็นหลักการที่ช่วยป้องกันเราจากการเปลี่ยนอินเทอร์เฟซที่มีอยู่โดยไม่ตั้งใจ (คลาสและวิธีการที่คุณโทรและวิธีที่คุณคาดหวังว่ามันจะทำงาน)

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

OC เป็นเศษส่วน แอปเปิ้ลในทุกระดับการออกแบบของคุณ ทุกคนคิดว่ามันใช้ได้เฉพาะในระดับชั้นเรียนเท่านั้น แต่มันก็สามารถใช้ได้อย่างเท่าเทียมกันในระดับวิธีหรือระดับแอสเซมบลี

การละเมิด OC บ่อยเกินไปในระดับที่เหมาะสมแนะนำว่าอาจถึงเวลาต้องปรับโครงสร้างแล้ว "ระดับที่เหมาะสม" เป็นการเรียกการตัดสินที่มีทุกอย่างที่เกี่ยวข้องกับการออกแบบโดยรวมของคุณ

การติดตาม Open-Closed แท้จริงหมายถึงจำนวนคลาสที่จะเกิดการระเบิด คุณจะสร้าง (ตัวพิมพ์ใหญ่ "I") การเชื่อมต่อโดยไม่จำเป็น คุณจะจบลงด้วยบิตของฟังก์ชั่นการแพร่กระจายในชั้นเรียนและจากนั้นคุณต้องเขียนโค้ดเพิ่มเติมจำนวนมากเพื่อรวมเข้าด้วยกัน เมื่อถึงจุดหนึ่งมันก็จะเริ่มขึ้นกับคุณว่าการเปลี่ยนชั้นเรียนเดิมจะดีขึ้น


2
"อาชญากรรมของการละเมิด OC น้อยกว่ามากเมื่อคุณสามารถเพิ่มวิธีการใหม่ในชั้นเรียนแทนที่จะต้องเปลี่ยนวิธีที่มีอยู่เดิม": เท่าที่ฉันเข้าใจการเพิ่มวิธีการใหม่ไม่ได้ละเมิดหลักการ OC (เปิดสำหรับการขยาย) เลย . ปัญหาคือการเปลี่ยนวิธีการที่มีอยู่ซึ่งใช้ส่วนต่อประสานที่กำหนดไว้อย่างดีดังนั้นจึงมีความหมายที่กำหนดไว้แล้ว (ปิดเพื่อแก้ไข) โดยหลักการแล้วการเปลี่ยนโครงสร้างไม่ได้เปลี่ยนความหมายดังนั้นความเสี่ยงเดียวที่ฉันเห็นคือการแนะนำบั๊กในโค้ดที่เสถียรและผ่านการทดสอบมาแล้ว
Giorgio

1
นี่คือคำตอบที่แสดงให้เห็น CodeReview เปิดให้บริการสำหรับส่วนขยาย การออกแบบระดับนั้นยืดออกได้ ในทางตรงกันข้ามการเพิ่มวิธีการแก้ไขชั้นเรียน
Radarbob

การเพิ่มวิธีการใหม่เป็นการละเมิด LSP ไม่ใช่ OCP
Tulains Córdova

1
การเพิ่มวิธีการใหม่ไม่ละเมิด LSP หากคุณเพิ่มวิธีการคุณได้แนะนำอินเทอร์เฟซใหม่ @ TulainsCórdova
RubberDuck

6

หลักการ Open-Closed ดูเหมือนจะเป็นหลักการที่ปรากฏก่อน TDD แพร่หลายมากขึ้น แนวคิดที่ว่ามีความเสี่ยงที่จะ refactor รหัสเพราะคุณอาจทำอะไรบางอย่างผิดพลาดดังนั้นจึงปลอดภัยกว่าที่จะปล่อยให้รหัสที่มีอยู่ตามเดิมและเพิ่มเข้าไปอีก ในกรณีที่ไม่มีการทดสอบนี้ทำให้รู้สึก ข้อเสียของวิธีการนี้คือการฝ่อรหัส ทุกครั้งที่คุณขยายชั้นเรียนแทนที่จะปรับโครงสร้างอีกครั้งคุณจะได้ชั้นเพิ่มอีก คุณเพียงแค่ใส่รหัสด้านบน ทุกครั้งที่คุณใส่รหัสมากขึ้นคุณจะเพิ่มโอกาสในการทำซ้ำ ลองนึกภาพ; มีบริการใน codebase ของฉันที่ฉันต้องการใช้ฉันพบว่ามันไม่มีสิ่งที่ฉันต้องการดังนั้นฉันจึงสร้างคลาสใหม่เพื่อขยายและรวมฟังก์ชันการทำงานใหม่ของฉัน นักพัฒนารายอื่นมาพร้อมกันในภายหลังและต้องการใช้บริการเดียวกัน น่าเสียดายที่พวกเขาไม่ได้ ไม่ทราบว่ามีเวอร์ชันเพิ่มเติมของฉันอยู่ พวกเขาใช้รหัสกับการใช้งานดั้งเดิม แต่พวกเขายังต้องการหนึ่งในคุณสมบัติที่ฉันเขียน แทนที่จะใช้เวอร์ชันของฉันตอนนี้พวกเขายังขยายการใช้งานและเพิ่มคุณสมบัติใหม่ ตอนนี้เรามีคลาสทั้งหมด 3 คลาสรุ่นแรกและรุ่นใหม่ที่มีฟังก์ชันการทำงานที่ซ้ำซ้อน ปฏิบัติตามหลักการเปิด / ปิดและการทำซ้ำนี้จะยังคงสร้างขึ้นในช่วงชีวิตของโครงการที่นำไปสู่ฐานรหัสที่ซับซ้อนโดยไม่จำเป็น

ด้วยระบบที่ผ่านการทดสอบอย่างดีไม่จำเป็นต้องฝืนรหัสนี้คุณสามารถ refactor code ได้อย่างปลอดภัยช่วยให้การออกแบบของคุณสามารถดูดซับความต้องการใหม่ ๆ ได้แทนที่จะต้องใช้รหัสใหม่อย่างต่อเนื่อง รูปแบบของการพัฒนานี้เรียกว่าการออกแบบที่เกิดขึ้นใหม่และนำไปสู่รหัสฐานที่สามารถอยู่ในสภาพดีตลอดอายุการใช้งานแทนที่จะค่อย ๆ รวบรวม cruft


1
ฉันไม่ได้เป็นผู้สนับสนุนของหลักการแบบเปิดหรือ TDD (ในแง่ที่ว่าฉันไม่ได้คิดค้นมัน) สิ่งที่ทำให้ฉันประหลาดใจก็คือมีคนเสนอหลักการแบบเปิดและการใช้การปรับโครงสร้างและ TDD ในเวลาเดียวกัน สิ่งนี้ขัดแย้งกับฉันดังนั้นฉันจึงพยายามหาวิธีนำแนวทางเหล่านี้ทั้งหมดมารวมกันเป็นกระบวนการที่สอดคล้องกัน
Giorgio

"ความคิดที่ว่ามีความเสี่ยงที่จะ refactor รหัสเพราะคุณอาจทำลายบางสิ่งบางอย่างดังนั้นจึงปลอดภัยกว่าที่จะปล่อยให้รหัสที่มีอยู่ตามเดิมและเพิ่มเข้าไปในนั้น": จริงๆแล้วฉันไม่เห็นด้วยวิธีนี้ แนวคิดนี้ค่อนข้างจะมีหน่วยเล็ก ๆ ที่มีอยู่ในตัวเองซึ่งคุณสามารถเปลี่ยนหรือขยายได้ (ซึ่งจะทำให้ซอฟต์แวร์สามารถวิวัฒนาการได้) แต่คุณไม่ควรสัมผัสแต่ละหน่วยเมื่อผ่านการทดสอบอย่างละเอียดแล้ว
Giorgio

คุณต้องคิดว่าคลาสจะไม่ถูกใช้เฉพาะใน codebase ของคุณ ห้องสมุดที่คุณเขียนสามารถใช้ในโครงการอื่น ดังนั้น OCP จึงเป็นสิ่งสำคัญ นอกจากนี้โปรแกรมเมอร์ใหม่ที่ไม่ทราบว่าคลาสที่ขยายเพิ่มขึ้นพร้อมฟังก์ชั่นที่เขา / เธอต้องการคือปัญหาด้านการสื่อสาร / เอกสารไม่ใช่ปัญหาด้านการออกแบบ
Tulains Córdova

@ TulainsCórdovaในรหัสแอปพลิเคชันซึ่งไม่เกี่ยวข้อง สำหรับรหัสห้องสมุดฉันขอยืนยันการกำหนดเวอร์ชันความหมายเป็นแบบที่ดีกว่าสำหรับการสื่อสารการเปลี่ยนแปลงที่เกิดขึ้น
opsb

1
@ TulainsCórdovaที่มีความเสถียรของรหัสไลบรารี API นั้นสำคัญกว่าเนื่องจากไม่สามารถทดสอบรหัสลูกค้าได้ ด้วยรหัสแอปพลิเคชันการทดสอบของคุณจะแจ้งให้คุณทราบถึงการแตกหักทันที อีกวิธีหนึ่งรหัสแอปพลิเคชันสามารถทำการเปลี่ยนแปลงที่ไม่มีความเสี่ยงในขณะที่รหัสไลบรารีต้องจัดการความเสี่ยงโดยการรักษา API ที่เสถียรและการส่งสัญญาณแตกโดยใช้เช่นการกำหนดเวอร์ชันทางความหมาย
opsb

6

ในคำพูดของคนธรรมดา:

A.หลักการของ O / C หมายถึงการที่จะต้องมีความเชี่ยวชาญเฉพาะทางโดยการขยายไม่ใช่โดยการปรับเปลี่ยนคลาสเพื่อรองรับความต้องการพิเศษ

B. การเพิ่มฟังก์ชันการทำงานที่ขาดหายไป (ไม่เฉพาะ) หมายความว่าการออกแบบไม่สมบูรณ์และคุณต้องเพิ่มลงในคลาสพื้นฐานโดยไม่ละเมิดสัญญา ฉันคิดว่านี่ไม่ได้ละเมิดหลักการ

C. การปรับโครงสร้างใหม่ไม่ได้ละเมิดหลักการ

เมื่อการออกแบบเติบโตขึ้นพูดหลังจากผ่านช่วงเวลาการผลิตไปแล้ว:

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

หลักการเปิด / ปิดเป็นความเข้าใจผิดอย่างมาก คะแนน A และ B ของคุณถูกต้องแน่นอน
gnasher729

1

สำหรับฉันหลักการ Open-Closed เป็นแนวทางไม่ใช่กฎที่ยากและรวดเร็ว

ในส่วนที่เกี่ยวกับหลักการเปิดคลาสสุดท้ายใน Java และคลาสใน C ++ พร้อมตัวสร้างทั้งหมดที่ประกาศเป็นส่วนตัวละเมิดส่วนเปิดของหลักการ open-closed มีกรณีการใช้งานที่ดี (หมายเหตุ: ของแข็งไม่ใช่ SOLID) สำหรับชั้นเรียนสุดท้าย การออกแบบเพื่อเพิ่มความสามารถเป็นสิ่งสำคัญ อย่างไรก็ตามสิ่งนี้ใช้เวลาในการมองการณ์ไกลและพยายามอย่างมากและคุณมักจะมองข้ามแนวการละเมิด YAGNI (คุณไม่จำเป็นต้องใช้มัน) และฉีดกลิ่นรหัสของการเก็งกำไรทั่วไป ควรเปิดองค์ประกอบซอฟต์แวร์ที่สำคัญสำหรับการขยายหรือไม่ ใช่. ทั้งหมดหรือไม่ ไม่นั่นในตัวมันเองเป็นเรื่องของการเก็งกำไร

ในส่วนที่เกี่ยวกับการปิดเมื่อไปจากรุ่น 2.0 ถึง 2.1-2.2 ถึง 2.3 ของผลิตภัณฑ์บางอย่างไม่ปรับเปลี่ยนพฤติกรรมเป็นความคิดที่ดีมาก ผู้ใช้ไม่ชอบมันทุกครั้งที่มีการเปิดตัวย่อยสลายรหัสของตัวเอง อย่างไรก็ตามตามวิธีที่เรามักพบว่าการใช้งานครั้งแรกในเวอร์ชัน 2.0 นั้นขาดพื้นฐานหรือข้อ จำกัด ภายนอกที่ จำกัด การออกแบบเริ่มต้นใช้ไม่ได้อีกต่อไป คุณยิ้มและรับไว้และดูแลการออกแบบนั้นในรีลีส 3.0 หรือไม่หรือคุณทำให้คอมแพตทิบิลิตี้แบบ non-backward 3.0 ในบางเรื่องหรือไม่? ความเข้ากันได้ย้อนหลังอาจเป็นข้อ จำกัด อย่างมาก ขอบเขตการวางจำหน่ายที่สำคัญเป็นสถานที่ที่ยอมรับความเข้ากันได้ย้อนหลัง คุณต้องระวังว่าการทำเช่นนี้อาจทำให้ผู้ใช้อารมณ์เสีย จะต้องมีกรณีที่ดีว่าทำไมการหยุดพักกับอดีตจึงเป็นสิ่งจำเป็น


0

การเปลี่ยนโครงสร้างตามคำจำกัดความกำลังเปลี่ยนโครงสร้างรหัสโดยไม่มีการเปลี่ยนแปลงพฤติกรรม ดังนั้นเมื่อคุณสร้างใหม่คุณจะไม่เพิ่มคุณสมบัติใหม่

สิ่งที่คุณทำเป็นตัวอย่างสำหรับหลักการ Open Open ที่ฟังดูโอเค หลักการนี้เป็นการขยายรหัสที่มีอยู่ด้วยคุณสมบัติใหม่

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

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

ไม่มีสิ่งเช่นการออกแบบที่สมบูรณ์แบบ ไม่มีการออกแบบดังกล่าวที่สามารถและควรเคารพหลักการหรือรูปแบบที่มีอยู่ทั้งหมด นั่นคือการเข้ารหัสยูโทเปีย

ฉันหวังว่าคำตอบนี้ช่วยคุณในภาวะที่กลืนไม่เข้าคายไม่ออกของคุณ อย่าลังเลที่จะขอคำชี้แจงหากจำเป็น


1
"ดังนั้นเมื่อคุณสร้างใหม่คุณจะไม่เพิ่มคุณสมบัติใหม่ ๆ ": แต่ฉันสามารถแนะนำบั๊กในซอฟต์แวร์ที่ผ่านการทดสอบแล้ว
Giorgio

"บางครั้งหลายครั้งหลังจากที่คุณเพิ่มคุณสมบัติที่สองและสามและ n-th คุณรู้ว่าการออกแบบครั้งแรกของคุณแม้ว่ามันจะเคารพ Open-Close ก็ไม่เคารพหลักการหรือข้อกำหนดซอฟต์แวร์อื่น ๆ ": นั่นคือเมื่อฉันจะ เริ่มเขียนการนำไปใช้ใหม่Bและเมื่อพร้อมแล้วให้แทนที่การนำไปใช้งานเก่าAด้วยการนำไปใช้ใหม่B(นั่นคือการใช้อินเทอร์เฟซเดียว) Aรหัสของสามารถใช้เป็นพื้นฐานสำหรับBรหัสของแล้วฉันสามารถใช้ refactoring ในBรหัสในระหว่างการพัฒนา แต่ฉันคิดว่าAรหัสทดสอบแล้วควรจะยังคงแช่แข็ง
Giorgio

@Giorgio เมื่อคุณ refactor คุณสามารถแนะนำข้อบกพร่องนั่นเป็นเหตุผลที่คุณเขียนการทดสอบ (หรือดีกว่าทำ TDD) วิธีที่ปลอดภัยที่สุดในการ refactor คือการเปลี่ยนรหัสเมื่อคุณรู้ว่ามันทำงานได้ คุณรู้เรื่องนี้โดยมีชุดทดสอบที่ผ่าน หลังจากที่คุณเปลี่ยนรหัสการผลิตการทดสอบจะต้องผ่านเพื่อให้คุณรู้ว่าคุณไม่ได้แนะนำข้อผิดพลาด และจำไว้ว่าการทดสอบมีความสำคัญเทียบเท่ากับรหัสการผลิตดังนั้นคุณจึงใช้กฎเดียวกันกับรหัสการผลิตและทำให้มันสะอาดอยู่เสมอ
Patkos Csaba

@Giorgio หากรหัสBถูกสร้างขึ้นบนรหัสAเป็นวิวัฒนาการของAเมื่อBปล่อยออกมาAควรถูกลบออกและไม่เคยใช้อีกครั้ง ก่อนหน้านี้ลูกค้าที่ใช้Aจะใช้Bโดยไม่ทราบเกี่ยวกับการเปลี่ยนแปลงเนื่องจากอินเตอร์เฟสIไม่เปลี่ยนแปลง (อาจจะเป็นหลักการทดแทน Liskov เล็กน้อยที่นี่ ... Lจาก SOLID)
Patkos Csaba

ใช่นี่คือสิ่งที่ฉันมีอยู่ในใจ: อย่าทิ้งรหัสการทำงานจนกว่าคุณจะมีการแทนที่ (ทดสอบอย่างดี) ที่ถูกต้อง
Giorgio

-1

ตามความเข้าใจของฉัน - ถ้าคุณเพิ่มวิธีการใหม่ในชั้นเรียนที่มีอยู่แล้วมันจะไม่ทำลาย OCP อย่างไรก็ตามฉันสับสนเล็กน้อยกับการเพิ่มตัวแปรใหม่ในคลาส แต่ถ้าคุณเปลี่ยนวิธีการและพารามิเตอร์ที่มีอยู่ในวิธีการที่มีอยู่แล้วมันจะทำลาย OCP แน่นอนเพราะรหัสได้รับการทดสอบแล้วและส่งผ่านถ้าเราตั้งใจเปลี่ยนวิธี [เมื่อต้องการเปลี่ยนแปลง] มันจะมีปัญหา

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.