การเปลี่ยนแปลงในการปฏิบัติงานละเมิดหลักการการทดแทน Liskov หรือไม่?


14

พูดว่าฉันมี:

interface Thing
{
    GetThing();
}

class FastThing : Thing 
{
    public int GetThing()
    {
        return 1;
    }
}

class SlowThing : Thing
{
    public int GetThing()
    {
        return GetThingFromDatabase();
    }
}

นี่เป็นการละเมิดหลักการทดแทน Liskov หรือไม่?


GetThingFromDatabase()ไม่ช้าพอที่จะทำให้การโต้เถียงนี้ Factor4096BitPublicKey();return 1;จะทำให้สิ่งต่าง ๆ น่าสนใจยิ่งขึ้น
Patrick

บาร์บาร่า Liskov เฉพาะเจาะจงมากเกี่ยวกับสิ่งที่เป็นและไม่ครอบคลุม
dietbuddha

1
หากคุณแทนที่FastThingด้วยSlowThingLSP จะไม่สามารถใช้งานได้ หากคุณเพิ่มความคิดเห็นThing::GetThingที่ระบุว่า "เร็วมาก" คุณสามารถพูดคุยคำถามได้
Cephalopod

คำตอบ:


14

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

แต่อินเทอร์เฟซจำนวนมากมีการรับประกันประสิทธิภาพโดยนัยหรือโดยระบุอย่างชัดเจนไม่ว่าจะในความซับซ้อนหรือในเวลาที่แบน ตัวอย่างเช่นใน C ++ Standard เป็นสิ่งผิดกฎหมายในการใช้งานไลบรารีด้วยการเรียกการบล็อกยกเว้นที่ Standard อนุญาตอย่างชัดแจ้ง


3
ประสิทธิภาพไม่ใช่สิ่งที่บังคับใช้ผ่านการตรวจสอบประเภท เป็นคำมั่นสัญญาของผู้ดำเนินการ / ผู้ดูแลห้องสมุด
dietbuddha

3
ฉันระบุไว้อย่างชัดเจนดังนั้นในคำตอบของฉัน?
DeadMG

1
ประเด็นของฉันคือเมื่อคุณรวมสิ่งอื่นนอกเหนือจากประเภทไว้ในเกณฑ์แล้วคุณจะไม่พูดถึง Liskov อีกต่อไปเนื่องจากเป็นประเภทเฉพาะ ในขณะที่ "การฝึกฝน" ของการไม่ย่อยวัตถุที่มีประสิทธิภาพแตกต่างกันออกไปอาจจะดี Liskov เองก็ไม่มีอะไรจะพูดเกี่ยวกับมัน
dietbuddha

7
Liskov ระบุว่าสำหรับ Derived ควรใช้งานได้ทุกที่ที่ Base เป็น นั่นอาจไม่เป็นจริงหากฐานรับประกันผลงานหรือคุณลักษณะบางอย่าง ตัวอย่างเช่นถ้าบล็อกที่ได้รับอาจมีศักยภาพสำหรับการหยุดชะงัก
DeadMG

8

TL; DR: ไม่

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


3
ฉันได้ดูเพียงสั้น ๆ ลงในกระดาษนั้น แต่คุณแน่ใจหรือว่าข้อ จำกัด เรื่องเวลาไม่สามารถพิสูจน์ได้อย่างเป็นทางการ? และแม้ว่า Liskov ไม่ได้หมายความว่าในคำพูดรวมถึงข้อ จำกัด เรื่องเวลาอาจถูกมองว่าเป็นส่วนขยายที่ดีของ LSP แบบคลาสสิกซึ่งอาจเกี่ยวข้องกับการเขียนโปรแกรมในโลกแห่งความเป็นจริง
Doc Brown

@Doc Brown: การจับเวลานั้นมีประโยชน์ในการพิจารณาเพื่อทดแทนวัตถุหรือไม่และเป็น orthogonal ถึง Liskov หากต้องการเพิ่มเป็นข้อบังคับแบบกระจาย แต่ไม่สามารถและจะไม่เป็นส่วนหนึ่งของ Liskov มันเหมือนกับมีสมการตรรกะบูลีนและพูดว่า! เท็จสามารถถูกแทนที่โดย True ถ้ามันเร็วพอ ความเร็วไม่เกี่ยวกับคณิตศาสตร์หรือตรรกะ
dietbuddha

ตัวอย่าง: รหัสนี้เรียกว่าใน EDT ของ Java หรือในวงเหตุการณ์ของโหนด ประสิทธิภาพที่ลดลงอย่างมากของเวอร์ชั่นช้าจะทำให้ซอฟต์แวร์แตกหัก ฉันคิดว่าคำตอบที่ถูกต้องสำหรับคำถามนี้คือ "อาจจะไม่ใช่ แต่มีข้อยกเว้น"
user949300

6

อินเทอร์เฟซทำอะไรรับประกัน ตั้งแต่GetThingทำให้ไม่มีการรับประกันแล้วชนิดย่อยไม่จำเป็นต้องเคารพมัน

ถ้าอินเตอร์เฟซที่เป็นสิ่งที่ต้องการGetThingInLinearTimeหรือถ้าพิมพ์ฐานเป็นเสมือนและการดำเนินการเริ่มต้นเป็นหนึ่งในความซับซ้อนนั้นการทำที่ซับซ้อนอัลกอริทึมที่เลวร้ายยิ่งจะละเมิด LSP


4

ประสิทธิภาพของซอฟต์แวร์ไม่เกี่ยวข้องกับหลักการทดแทน Liskov

หลักการเกี่ยวข้องกับการทดแทนชนิดย่อยและผลกระทบเชิงพฤติกรรมของการทดแทนวัตถุนั้นในเงื่อนไข OOP เท่านั้น

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


1

มันมีความสำคัญต่อสิ่งที่หลักการทดแทนของ Liskov พูดอย่างเจาะจงหรือไม่? หากประเภทย่อยละเมิดความคาดหวังของผู้บริโภคของประเภทซุปเปอร์ที่ดูเหมือนว่าสิ่งที่ไม่ดีโดยไม่คำนึงว่า LSP มีข้อ จำกัด มากขึ้น

ดังนั้นในมุมมองของฉันว่าความคาดหวังที่สมเหตุสมผลของผู้บริโภคเกี่ยวกับสิ่งที่เป็นนามธรรมนั้นเป็นจริงหรือไม่โดยกลุ่มย่อยดูเหมือนจะเป็นลักษณะทั่วไปที่ดีของ LSP

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


2
เท่าที่ฉันจะบอกได้ตัวอย่างที่โพสต์ไม่ใช่ Java
gnat

0

ลุงบ๊อบตอบคำถามที่คล้ายกันมากซึ่งเขากล่าวว่าการละเมิด LSP ต้องการ 3 ฝ่าย:

Type T, Subtype S และโปรแกรม P ที่ใช้ T แต่ให้อินสแตนซ์ของ S

ฉันเดาว่าคำถามนี้มีโครงสร้างคล้ายกันกับที่เขาตอบกลับโดยที่ไม่ได้พูดถึงPที่ใช้Tและพฤติกรรมที่Pคาดหวัง

คุณสามารถค้นหาของเขาคำตอบที่นี่ (คุณจะต้องเลื่อนลงมาและหาคำตอบจากผู้ใช้ชื่อ Robert Martin)


1
คำถามนี้ถามคำถามนี้อย่างไร
ริ้น

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