รูปแบบของปัญหาทั่วไปที่ได้รับประโยชน์จากรหัสที่ออกแบบมาเพื่อใช้ประโยชน์หลายอย่างของมรดกคืออะไร
นี่เป็นเพียงตัวอย่างเดียว แต่เป็นสิ่งที่ฉันพบว่ามีค่ายิ่งในการปรับปรุงความปลอดภัยและลดการล่อลวงเพื่อใช้การเปลี่ยนแปลงแบบเรียงซ้อนตลอดทั้งผู้โทรหรือคลาสย่อย
ที่ฉันได้พบการสืบทอดหลายอย่างที่มีประโยชน์อย่างไม่น่าเชื่อแม้จะเป็นนามธรรมที่สุดอินเตอร์เฟสไร้สัญชาติคืออินเทอร์เฟซที่ไม่เสมือน (NVI) ใน C ++
พวกเขาไม่ได้มีคลาสพื้นฐานที่เป็นนามธรรมมากเท่าอินเทอร์เฟซที่มีเพียงเล็กน้อยในการปรับใช้กับพวกเขาเพื่อบังคับใช้แง่มุมสากลของสัญญาของพวกเขาเนื่องจากพวกเขาไม่ได้ จำกัด วงทั่วๆไปของสัญญา .
ตัวอย่างง่าย ๆ (บางคนอาจตรวจสอบว่าตัวจัดการไฟล์ที่ส่งผ่านนั้นเปิดอยู่หรืออะไรทำนองนั้น):
// Non-virtual interface (public methods are nonvirtual/final).
// Since these are modeling the concept of "interface", not ABC,
// multiple will often be inherited ("implemented") by a subclass.
class SomeInterface
{
public:
// Pre: x should always be greater than or equal to zero.
void f(int x) /*final*/
{
// Make sure x is actually greater than or equal to zero
// to meet the necessary pre-conditions of this function.
assert(x >= 0);
// Call the overridden function in the subtype.
f_impl(x);
}
protected:
// Overridden by a boatload of subtypes which implement
// this non-virtual interface.
virtual void f_impl(int x) = 0;
};
ในกรณีนี้อาจf
ถูกเรียกโดยหนึ่งพันแห่งใน codebase ในขณะที่f_impl
ถูกแทนที่ด้วยคลาสย่อยกว่าร้อย
มันจะเป็นเรื่องยากที่จะทำชนิดของการตรวจสอบความปลอดภัยในทุกสถานที่ที่ 1000 โทรf
หรือทั้งหมด 100 f_impl
สถานที่ที่แทนที่
เพียงแค่ทำให้จุดเริ่มต้นนี้เข้ากับฟังก์ชั่นที่ไม่ใช่เสมือนมันทำให้ฉันอยู่ศูนย์กลางเดียวที่จะทำการตรวจสอบนี้ และการตรวจสอบนี้ไม่ได้ลดสิ่งที่เป็นนามธรรมให้เหลือน้อยที่สุดเพราะเป็นการยืนยันเงื่อนไขที่จำเป็นในการเรียกใช้ฟังก์ชันนี้ เรียกได้ว่าเป็นการเสริมความแข็งแกร่งให้สัญญาโดยอินเตอร์เฟสและลดภาระในการตรวจสอบx
อินพุตเพื่อให้แน่ใจว่าสอดคล้องกับเงื่อนไขที่ถูกต้องใน 100 แห่งที่แทนที่มัน
มันเป็นสิ่งที่ฉันต้องการให้ทุกภาษามีและต้องการแม้แต่ใน C ++ ว่ามันเป็นแนวคิดดั้งเดิมมากกว่าเล็กน้อย (เช่น: ไม่ต้องการให้เรากำหนดฟังก์ชันแยกต่างหากเพื่อแทนที่)
นี้จะเป็นประโยชน์อย่างยิ่งถ้าคุณไม่ได้ทำเช่นนี้assert
ล่วงหน้าและตระหนักถึงคุณจำเป็นต้องใช้มันในภายหลังเมื่อบางสถานที่สุ่มใน codebase f
กำลังเผชิญหน้ากับค่าลบจะถูกส่งผ่านไปยัง