เป็นการละเมิดหลักการ Open-Closed หรือไม่ในการอัพเดทค่าคงที่ซึ่งแสดงถึงมูลค่าที่แท้จริงของโลก?


10

ฉันมีชั้นเรียนที่คำนวณรายได้สุทธิต่อปีของคนงาน มันมีค่าคงที่คิดเป็นร้อยละภาษี แต่วันหนึ่งอัตราภาษีมีการเปลี่ยนแปลงดังนั้นฉันต้องแก้ไขรหัส

การกระทำของการแก้ไขค่าคงที่นี้บ่งบอกถึงการละเมิดหลักการ Open-Closedเนื่องจากมันเป็นหลักว่าชั้นควรจะปิดเพื่อแก้ไข?


10
ซอฟต์แวร์เปลี่ยนแปลงเนื่องจากโลกแห่งความจริงเปลี่ยนแปลง ในทางกลับกันการสร้างเปอร์เซ็นต์ภาษีค่าคงที่ไม่ได้เป็นการละเมิดหลักการ Open-Closed มากนักเพราะมันเป็นเพียงสิ่งที่ไม่รู้จะทำอย่างไร เปอร์เซ็นต์ภาษีเป็นรายการที่เปลี่ยนแปลงได้ชัดเจนซึ่งควรถูกผูกไว้ในขณะใช้งาน
Richard Chambers

4
ฉันเห็นด้วยกับริชาร์ดอย่างสมบูรณ์ หากคุณต้องเปลี่ยนรหัสเพื่อแก้ไข "ค่าคงที่" OCP เป็นปัญหาของคุณอย่างน้อยที่สุด
Robert Harvey

3
สิ่งที่ก่อให้เกิดการละเมิด OCP นั้นมีความเป็นส่วนตัวสูงและสิ่งทั้งหมดนั้นค่อนข้างล้าสมัยอยู่แล้ว (เนื่องจากการสืบทอดการดำเนินการไม่ใช่วิธีปฏิบัติที่ดีที่สุดอีกต่อไป) นี่เป็นคำถามทั่วไปที่คุณต้องเดาว่าคนที่ถามคำถามนั้นคิดอย่างไร
Robert Bräutigam

2
@DocBrown: สิ่งที่ถือว่าเป็น "ข้อกำหนดใหม่"? คุณแสดงรหัสให้ฉันฉันสามารถชี้ให้เห็นข้อกำหนดใหม่ซึ่งจะต้องมีการเปลี่ยนรหัสอย่างแน่นอนไม่ว่า OCP จะสอดคล้องกับคุณอย่างไร ดังนั้นกลับไปที่คำถาม: หากนักพัฒนาถามผู้เชี่ยวชาญทางธุรกิจเกี่ยวกับเรื่องนี้และไม่มีการคาดหวังว่าอัตราภาษีจะเปลี่ยนแปลงไปมากกว่าหนึ่งครั้งในทุก ๆ สองสามปีที่ผ่านมา เพียงแค่ให้มันง่ายและเตรียมความพร้อมสำหรับสิ่งที่คุณรู้ว่า และสำหรับสิ่งเหล่านั้นแน่นอนทำให้มันเป็นชั้นนอก ดังนั้นจึงขึ้นอยู่กับ
Robert Bräutigam

1
@ RobertBräutigam: ประเด็นของฉันคือไม่มี IMHO เช่น "OCP สอดคล้อง" มีเพียง "OCP สอดคล้องในบริบทของหมวดหมู่ของข้อกำหนด" อาจมีความเป็นส่วนตัวบางอย่างที่องค์ประกอบควรจะเป็น "OCP สอดคล้อง" แต่ในกรณีที่อธิบายไว้ในคำถามนี้วิธีที่ฉันเข้าใจข้อกำหนดที่เปลี่ยนแปลงได้ถูกระบุไว้แล้วดังนั้น "ระดับการคำนวณรายได้" นี้อย่างชัดเจนไม่ได้เชื่อฟัง OCP ในบริบทของข้อกำหนดเฉพาะนี้
Doc Brown

คำตอบ:


14

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

หาก B, C และ D สามารถใช้หรือนำคลาสที่จัดไว้ให้กลับมาใช้ใหม่สำหรับกรณีการใช้งานที่แตกต่างกันโดยไม่จำเป็นต้องแก้ไขซอร์สโค้ดของไลบรารีดังนั้นคอมโพเนนต์จะตอบสนอง OCP ( ตามหมวดหมู่ของกรณีการใช้งาน ) มีวิธีการที่แตกต่างกันเพื่อให้บรรลุเช่นนี้

  • การทำให้คลาสสืบทอดได้ (โดยทั่วไปจะใช้ร่วมกับรูปแบบเมธอดเทมเพลตหรือรูปแบบกลยุทธ์)

  • โดยให้ "จุดฉีด" สำหรับการฉีดพึ่งพา

  • โดยการจัดเตรียมพารามิเตอร์การกำหนดค่าสำหรับคลาสหรือส่วนประกอบ (ตัวอย่างเช่นโดยมีพารามิเตอร์ตัวสร้าง "อัตราภาษี" ในกรณีของคุณหรือโดยใช้กลไกการกำหนดค่าอื่น ๆ )

  • อาจหมายถึงวิธีอื่นขึ้นอยู่กับภาษาการเขียนโปรแกรมหรือระบบนิเวศ

ตัวอย่างทั่วไปที่คุณพบในหนังสือข้อความมักเป็นประเภทที่หนึ่งหรือที่สอง (ฉันเดาว่าเพราะในสายตาของผู้แต่งหนังสือเหล่านั้นประเภทที่สามนั้นเล็กน้อยเกินกว่าที่จะกล่าวถึง)

อย่างที่คุณเห็นสิ่งนี้ไม่เกี่ยวข้องกับการห้ามการเปลี่ยนแปลงของซอร์สโค้ดโดยผู้ขาย A (เช่นการแก้ไขข้อผิดพลาดการปรับให้เหมาะสมหรือเพิ่มคุณสมบัติใหม่ในลักษณะที่เข้ากันได้แบบย้อนหลัง) ซึ่งค่อนข้างไม่เกี่ยวข้องกับ OCP OCP นั้นเกี่ยวกับวิธีที่ A ออกแบบอินเตอร์เฟสและความละเอียดของส่วนประกอบใน lib ดังนั้นสถานการณ์ reusage ที่แตกต่างกัน (เช่น resuage ด้วยอัตราภาษีที่แตกต่างกัน) ไม่ได้กระตุ้นให้เกิดการเปลี่ยนแปลงโดยอัตโนมัติ

ดังนั้นแม้จะมีสิ่งที่คนอื่นบอกคุณที่นี่คำตอบนั้นชัดเจนว่า"ใช่"มันจะเป็นการละเมิด OCP

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


ตกลงดังนั้น OCP จึงเกี่ยวกับการแสดงพฤติกรรมที่สามารถขยายได้สำหรับกรณีการใช้งานที่แตกต่างกันด้วยหนึ่งในสามวิธีที่คุณระบุไว้ใช่ไหม แต่ถ้าเป็นตัวอย่างของ OP ที่บอกเป็นนัยว่ามีบางอย่างพื้นฐานกำลังจะเปลี่ยน? ฉันไม่รู้ว่าประเทศ OP มาจากไหน แต่ในอัตราภาษีของประเทศฉันเป็นสิ่งที่ไม่เปลี่ยนแปลงบ่อยนัก มันเป็นตัวอย่างที่ไม่ดี แต่บางทีมันอาจถูกดึงออกมาอย่างคงที่เพื่อเน้นจุดนั้น ฉันค่อนข้างแน่ใจว่ามันไม่ได้หมายถึงการกำหนดค่าหรือขยายได้ ดังนั้นอาจมีคำถามเกี่ยวกับ "นี่ไม่เกี่ยวกับการห้ามเปลี่ยนแปลงใด ๆ ของซอร์สโค้ดโดยผู้ขาย A" ส่วน
Vadim Samokhin

อย่างน้อยฉันก็เข้าใจอย่างนั้น คนที่น่าสงสารที่ลบคำตอบที่เขายอมรับก็ไม่เช่นนั้นฉันก็เดา คุณเห็นมันจากมุมที่ต่างออกไปเล็กน้อย - ฉันเข้าใจประเด็นของคุณและเห็นด้วยกับมัน แต่ดูเหมือนว่าความคิดเห็นที่ฉลาดที่สุดได้รับจาก @Robert Bräutigam จนถึงตอนนี้ฉันยังไม่ทราบว่า OCP นั้นเป็นอัตวิสัย
Vadim Samokhin

1
ฉันเดาว่าฉันเคยถูกถามคำถามเดียวกันหรือไม่มีคำถามหนึ่งข้อที่ฉันควรถามโดยตอบว่า: "พฤติกรรมนั้นควรจะขยายออกไปหรือตั้งค่าไว้อย่างไร" ถ้าใช่ - การปรับเปลี่ยนคลาสโดยตรงนั้นเป็นการละเมิด OCP หากไม่มี - เกิน OCP จะไม่สามารถใช้งานได้ในสถานการณ์นั้น
Vadim Samokhin

1
@Zapadlo: ฉันคิดว่าถ้าองค์ประกอบทำตาม OCP สำหรับคลาสของข้อกำหนดไม่ได้เป็นอัตนัย - มันค่อนข้างชัดเจนในกรณีส่วนใหญ่หากข้อกำหนดใหม่จำเป็นต้องมีการแก้ไขซอร์สโค้ดของส่วนประกอบหรือถ้าส่วนประกอบรองรับข้อกำหนดนี้ ." แนวทางที่เป็นไปได้ที่จะใช้มันไม่ได้ จำกัด 3 วิธีแรกที่ผมแสดงดูแก้ไขของฉันความคิดของการกระทำอาจจะเกิดเพราะ OCP เพียงแค่มีชื่อที่ทำให้เข้าใจผิดและไม่ดีสวยได้อธิบายไว้ในจำนวนมากตำรา..
หมอ สีน้ำตาล

ความคิดส่วนตัวของฉันเกิดจากความจริงที่ว่าฉันไม่เข้าใจสิ่งที่คุณพูดอย่างเต็มที่ - แต่ตอนนี้ฉันเดาแล้ว ขอบคุณมากสำหรับความคิดเห็นที่ลึกซึ้งและคำตอบของคุณ
Vadim Samokhin

4

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

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

ในระยะยาวคุณอาจพบว่าปัญหาภาษีต้องการมากกว่าร้อยละ - ตัวอย่างเช่นวันหนึ่งกฎหมายภาษีมีความซับซ้อนมากขึ้นและต้องใช้หลายเปอร์เซ็นต์และค่าคงที่บางอย่าง (เช่นจำนวนเงินต่ำกว่า $ 10k ที่เก็บภาษีที่ X% ในขณะที่ ภาษีที่เหลืออยู่ที่ Y%)

นี่เป็นการแนะนำโดยใช้รูปแบบกลยุทธ์ที่ชั้นเรียนหลักในคำถามที่นี่ยอมรับวัตถุกลยุทธ์สำหรับการคำนวณภาษี

กลยุทธ์ต่างๆ (และ% ของและค่าคงที่ $) ควรจะสามารถเลือกได้จากไฟล์การกำหนดค่าและตอนนี้การเพิ่มกลยุทธ์ใหม่ต้องเพิ่มรหัสใหม่บางอย่าง แต่ไม่จำเป็นต้องปรับปรุงรหัสที่มีอยู่

แต่ละกลยุทธ์อาจรู้วิธีแยก / ตีความอาร์กิวเมนต์การกำหนดค่าภายนอกของตัวเองพร้อมกับวิธีคำนวณภาษีจริง

ภาษีอาจขึ้นอยู่กับสถานที่ที่ควบคุมดังนั้นคุณอาจมีสถานที่ที่เกี่ยวข้องกับรายได้หรือกับพนักงาน (หรือทั้งสองอย่าง) ในการกำหนดค่าภายนอกเราอาจเชื่อมโยงตำแหน่งที่ตั้งกับกลยุทธ์ด้านภาษี


ดูการฉีดที่พึ่งพาซึ่งเราจัดการสิ่งเหล่านี้อย่างชัดเจน


1
คำถามไม่ใช่ว่ามันเป็นความคิดที่ดีที่จะฝังบางสิ่งเช่นเปอร์เซ็นต์ภาษีในรหัสฉันแน่ใจว่าเป็นสิ่งที่ชัดเจนสำหรับพวกเราส่วนใหญ่ที่นี่ (รวมถึง OP) คำถามคือ "สิ่งนี้ละเมิด OCP หรือไม่" ดังนั้นฉันไม่เห็นว่าคำตอบของคุณอ้างถึงคำถามนี้อย่างไร
Doc Brown

1

ถ้าคุณต้องการแก้ไขคลาสเพื่อเปลี่ยนค่าภาษีการออกแบบของคลาสนั้นละเมิด OCP การออกแบบที่เหมาะสมสำหรับสิ่งที่คุณได้อธิบายไปนั้นมีไว้สำหรับคลาสเครื่องคิดเลขเพื่อรับค่าภาษีเป็นพารามิเตอร์

หากคลาสของคุณไม่ได้ใช้งาน (หมายถึงไม่ใช่คลาสแบบสแตติก) โดยการทำให้คุณสมบัติคลาสตัวแปรภาษีมีค่าถูกแทรกผ่านตัวสร้างคุณจะปรับปรุงการทำงานร่วมกันของคลาสด้วย

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


0

เห็นด้วยอย่างยิ่งกับ @Becuzz และฉันแค่ต้องการสรุปสิ่งนี้: OCP เกี่ยวข้องกับการค้นหา abstractions ที่นำมาใช้ใหม่ (ซึ่งมีประโยชน์) ที่ถูกฉีดเข้าไปในชั้นเรียน ดังนั้นพฤติกรรมของคลาสจึงไม่ได้ถูกแก้ไขโดยการเปลี่ยนรหัส แต่เป็นการให้การใช้งานที่แตกต่างกัน สิ่งนี้ทำให้ชัดเจนในหนังสือของ Robert Martin เรื่อง " การพัฒนาซอฟต์แวร์หลักการรูปแบบและวิธีปฏิบัติ " ของAgileให้ตรวจสอบบทที่เกี่ยวข้อง "หลักการเปิด - ปิด" บทย่อย "Abstraction is the Key" มันอธิบายความเข้าใจผิดอื่น ๆ ว่าพฤติกรรมสามารถแก้ไขได้ด้วยการสืบทอดเท่านั้น Bertrand Meyer เป็นผู้เสนอว่าในปี 1988 ในหนังสือของเขา“ การก่อสร้างซอฟต์แวร์เชิงวัตถุ ” ไม่ใช่ Robert Martin


-2

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


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