กลับไปหน้าบทความ

อ่าน 5 นาที

หลักการทดแทนของลิสคอฟ

หลักการ ทดแทนของ Liskov ( LSP ) เป็นคำจำกัดความเฉพาะของ ความสัมพันธ์การกำหนด ประเภทย่อย ที่เรียกว่า การกำหนดประเภทย่อยเชิงพฤติกรรมที่แข็งแกร่ง ซึ่ง Barbara Liskov...

หลักการทดแทนของลิสคอฟ

ภาพเหมือนของบาร์บารา ลิสคอฟ
วิธีการแทนที่แบบลิสคอฟ (Liskov substitution) ถูกนำเสนอโดยบาร์บารา ลิสคอ

หลักการทดแทนของ Liskov ( LSP ) เป็นคำจำกัดความเฉพาะของ ความสัมพันธ์การกำหนด ประเภทย่อยที่เรียกว่าการกำหนดประเภทย่อยเชิงพฤติกรรมที่แข็งแกร่ง ซึ่ง Barbara Liskovได้นำเสนอเป็นครั้งแรก ในสุนทรพจน์ หลักในการประชุมปี 1987 ในหัวข้อData abstraction and hierarchy หลักการ นี้อิงตามแนวคิดของ "ความสามารถในการทดแทน" ซึ่งเป็นหลักการในการเขียนโปรแกรมเชิงวัตถุที่ระบุว่าวัตถุของคลาสแม่สามารถถูกแทนที่ด้วยวัตถุของคลาสย่อยได้โดยไม่ทำให้โปรแกรมเสียหาย หลักการนี้เป็น ความสัมพันธ์ เชิงความหมายมากกว่าความสัมพันธ์เชิงไวยากรณ์เพียงอย่างเดียว เนื่องจากมีจุดประสงค์เพื่อรับประกันความสามารถในการทำงานร่วมกันเชิงความหมายของประเภทในลำดับชั้น โดยเฉพาะอย่างยิ่งประเภทวัตถุ Barbara Liskov และJeannette Wingได้อธิบายหลักการนี้อย่างกระชับในบทความปี 1994 ดังนี้: [ 1 ]

ข้อกำหนดของชนิดย่อย : ให้⁠ ⁠เป็นคุณสมบัติที่พิสูจน์ได้เกี่ยวกับวัตถุ⁠ ⁠ของชนิดTแล้ว⁠ ⁠ควรเป็นจริงสำหรับวัตถุ⁠ ⁠ของชนิดSโดยที่Sเป็นชนิดย่อยของT

ในเชิงสัญลักษณ์: กล่าวคือ ถ้าSเป็นชนิดย่อย ของ Tสิ่งที่ใช้ได้กับ วัตถุ Tก็จะใช้ได้กับ วัตถุ Sด้วย ในบทความเดียวกันนั้น Liskov และ Wing ได้อธิบายรายละเอียดเกี่ยวกับแนวคิดเรื่องการกำหนดชนิดย่อยเชิงพฤติกรรมในส่วนขยายของตรรกะ Hoareซึ่งมีความคล้ายคลึงกับการออกแบบโดยสัญญาของBertrand Meyerในแง่ที่ว่ามันพิจารณาปฏิสัมพันธ์ของการกำหนดชนิดย่อยกับเงื่อนไขก่อนหน้า เงื่อนไข ภายหลังและตัวแปรคงที่

หลักการ

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

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

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

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

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

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

ต้นกำเนิด

กฎเกี่ยวกับเงื่อนไขก่อนและหลังการทำงานนั้นเหมือนกับที่เบอร์ทรานด์ เมเยอร์นำเสนอในหนังสือObject-Oriented Software Construction ปี 1988 ของเขา ทั้งเมเยอร์และต่อมาปิแอร์ อเมริกา ซึ่งเป็นคนแรกที่ใช้คำว่าbehavioral subtypingได้ให้ คำจำกัดความ เชิงทฤษฎีการพิสูจน์ของแนวคิด behavioral subtyping บางประการ แต่คำจำกัดความของพวกเขาไม่ได้คำนึงถึงการตั้งชื่อซ้ำซ้อน (aliasing)ที่อาจเกิดขึ้นในภาษาโปรแกรมที่รองรับการอ้างอิงหรือตัวชี้ การคำนึงถึงการตั้งชื่อซ้ำซ้อนเป็นการปรับปรุงที่สำคัญที่ลิสคอฟและวิง (1994) ได้ทำขึ้น และส่วนประกอบสำคัญคือข้อจำกัดด้านประวัติ (history constraint) ภายใต้คำจำกัดความของเมเยอร์และอเมริกา จุดที่เปลี่ยนแปลงได้จะเป็น behavioral subtype ของจุดที่ไม่เปลี่ยนแปลงได้ ในขณะที่หลักการแทนที่ของลิสคอฟห้ามสิ่งนี้

การละเมิด

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

นี่อาจเป็นตัวอย่างหนึ่งของการละเมิดหลักการ LSP:

คลาสRectangle { private : double width ; double height ; public : Rectangle ( double width , double height ) : width { width }, height { height } {} }// ประกาศเป็น virtual สำหรับคลาสย่อย Square virtual void setWidth ( double width ) noexcept { this -> width = width ; }// ประกาศเป็น virtual สำหรับคลาสย่อย Square virtual void setHeight ( double height ) noexcept { this -> height = height ; }[[ nodiscard ]] double getWidth () const noexcept { return width ; }[[ nodiscard ]] double getHeight () const noexcept { return height ; }[[ nodiscard ]] double getArea () const noexcept { return width * height ; } };

จากมุมมองการเขียนโปรแกรมSquareคลาสนี้สามารถนิยามได้ว่าเป็นการสืบทอดมาจากRectangleคลาสอื่น

คลาสSquare : public Rectangle { public : void setWidth ( double width ) noexcept override { Rectangle :: setWidth ( width ); Rectangle :: setHeight ( width ); }void setHeight ( double height ) noexcept override { Rectangle :: setHeight ( height ); Rectangle :: setWidth ( height ); } };

อย่างไรก็ตาม การกระทำนี้ขัดกับหลักการ LSP แม้ว่า ความสัมพันธ์ แบบ is-aจะยังคงอยู่ระหว่างRectangleและSquareก็ตาม

ลองพิจารณาตัวอย่างต่อไปนี้ ซึ่งฟังก์ชันgจะไม่ทำงานหากSquareมีการส่งค่า a เข้าไป ดังนั้นหลักการเปิด-ปิดอาจถือได้ว่าถูกละเมิด

void g ( Rectangle & r ) { r . setWidth ( 5 ); r . setHeight ( 4 ); assert ( r . getArea () == 20 ); // การตรวจสอบจะล้มเหลว}

ในทางกลับกัน หากพิจารณาว่าประเภทของรูปทรงควรเป็นข้อจำกัดเฉพาะความสัมพันธ์ของมิติเท่านั้น สมมติฐานที่g()ว่าความsetHeight()สูงและพื้นที่จะเปลี่ยนแปลง แต่ความกว้างจะไม่เปลี่ยนแปลงนั้นถือว่าไม่ถูกต้อง สมมติฐานนี้ไม่ถูกต้องไม่เพียงแต่สำหรับรูปสี่เหลี่ยมจัตุรัสเท่านั้น แต่ยังอาจไม่ถูกต้องสำหรับรูปสี่เหลี่ยมผืนผ้าอื่นๆ ที่อาจถูกเข้ารหัสเพื่อรักษาพื้นที่หรืออัตราส่วนด้านเมื่อความสูงเปลี่ยนแปลง[ 4 ]

ดูเพิ่มเติม

บรรณานุกรม

เอกสารอ้างอิงเฉพาะ

  • ลิสคอฟ, บี. (1987). "ปาฐกถาหลัก - การนามธรรมของข้อมูลและลำดับชั้น" ภาคผนวกของรายงานการประชุมเรื่องระบบ ภาษา และแอปพลิเคชันการเขียนโปรแกรมเชิงวัตถุ (ภาคผนวก) - OOPSLA '87หน้า  17–34 . doi : 10.1145/62138.62141 . ISBN 0897912667.สุนทรพจน์สำคัญที่ลิสคอฟได้กล่าวถึงหลักการนี้เป็นครั้งแรก
  • Meyer, B. (1988). การสร้างซอฟต์แวร์เชิงวัตถุ . Prentice Hall. ISBN 0-13-629031-0.

ข้อมูลอ้างอิงทั่วไป

  • ลีเวนส์, แกรี่ ที. ; ธารา, กฤษณะ เค. (2000). "แนวคิดของการแบ่งประเภทพฤติกรรมย่อยและภาพร่างของการขยายแนวคิดดังกล่าวไปยังระบบที่ใช้ส่วนประกอบเป็นฐาน" ใน ลีเวนส์, แกรี่ ที. ; สิตารามัน, มูราลี (บรรณาธิการ). พื้นฐานของระบบที่ใช้ส่วนประกอบเป็นฐาน . สำนักพิมพ์มหาวิทยาลัยเคมบริดจ์. ISBN 0-521-77164-1.บทความนี้สำรวจแนวคิดต่างๆ เกี่ยวกับการจำแนกประเภทพฤติกรรมย่อย รวมถึงแนวคิดของลิสคอฟและวิง
  • Liskov, BH ; Wing, JM (พฤศจิกายน 1994). "แนวคิดเชิงพฤติกรรมของการแบ่งประเภทย่อย" . ACM Trans. Program. Lang. Syst. 16 (6): 1811– 41. doi : 10.1145/197320.197383 . S2CID  999172 .ฉบับปรับปรุงใหม่ปรากฏขึ้น: Liskov, Barbara ; Wing, Jeannette (กรกฎาคม 1999). การกำหนดประเภทย่อยเชิงพฤติกรรมโดยใช้ตัวแปรคงที่และข้อจำกัด (รายงานทางเทคนิค). มหาวิทยาลัยคาร์เนกีเมลลอน. CMU-CS-99-156.การกำหนดหลักการอย่างเป็นทางการโดยผู้ประพันธ์
  • Plösch, Reinhold (2004). สัญญา สถานการณ์จำลอง และต้นแบบ: แนวทางบูรณาการเพื่อซอฟต์แวร์คุณภาพสูง . Springer. ISBN 3-540-43486-0.บทที่ 2 นำเสนอการแนะนำอย่างค่อยเป็นค่อยไปเกี่ยวกับการแบ่งประเภทพฤติกรรมย่อยในรูปแบบต่างๆ
  • Martin, Robert C. (มีนาคม 1996). "หลักการแทนที่ของ Liskov" (PDF) . C++ Report . เก็บถาวรจากต้นฉบับ(PDF)เมื่อ 28 พฤศจิกายน 2015บทความยอดนิยมในกลุ่มผู้เขียนโปรแกรมเชิงวัตถุ ซึ่งยกตัวอย่างการละเมิดหลักการ LSP (Level of SP) หลายประการ
  • Majorinc, Kazimir. "ปัญหาวงรี-วงกลมและการสืบทอดแบบผกผัน" . ITI 98, รายงานการประชุมวิชาการนานาชาติครั้งที่ 20 ด้านอินเทอร์เฟซเทคโนโลยีสารสนเทศ, ปูลา, 1998 . อินเทอร์เฟซเทคโนโลยีสารสนเทศ, 2009. ITI '09. รายงานการประชุมวิชาการนานาชาติครั้งที่ 31 ด้าน ITI 2009 หน้า  627–632 . ISSN  1330-1012 . OCLC  894960131 .บทความนี้กล่าวถึง LSP ในบริบทที่กล่าวถึงข้างต้น
  • Norvell, TS "หลักการทดแทนของ Liskov" (PDF) . มหาวิทยาลัยวิศวกรรมศาสตร์ Memorial .
  • Samokhin, Vadim (2018-06-06). "หลักการทดแทนของลิสคอฟ" . Medium .
  • "การออกแบบคลาส SOLID: หลักการทดแทนของลิสคอฟ"ทอมดัลลิง 21 พฤศจิกายน 2552
  • Jobaer, Abu (31 พฤษภาคม 2023). "LSP: หลักการทดแทนของลิสคอฟ" . The Startup . Medium.
ดึงข้อมูลมาจาก " https://en.wikipedia.org/w/index.php?title=Liskov_substitution_principle&oldid=1356218252 "

สรุปเนื้อหา

ข้อมูลสำคัญจากบทความ

ข้อมูลสำคัญเกี่ยวกับ หลักการทดแทนของลิสคอฟ

หลักการ ทดแทนของ Liskov ( LSP ) เป็นคำจำกัดความเฉพาะของ ความสัมพันธ์การกำหนด ประเภทย่อย ที่เรียกว่า การกำหนดประเภทย่อยเชิงพฤติกรรมที่แข็งแกร่ง ซึ่ง Barbara Liskov...

หลักการ

แนวคิดเรื่องชนิดย่อยเชิงพฤติกรรมของลิสคอฟได้กำหนดแนวคิดเรื่องความสามารถในการทดแทนกันได้สำหรับวัตถุ กล่าวคือ ถ้า S เป็นชนิดย่อยของ T แล้ววัตถุประเภท T ในโปรแกรมสามารถถูกแทนที่ด้วยวัตถุประเภท ได้ S โดยไม่เปลี่ยนแปลงคุณสมบัติที่พึงประสงค์ใดๆ ของโปรแกรมนั้น (เช่น...

ต้นกำเนิด

กฎเกี่ยวกับเงื่อนไขก่อนและหลังการทำงานนั้นเหมือนกับที่เบอร์ทรานด์ เมเยอร์นำเสนอในหนังสือ Object-Oriented Software Construction ปี 1988 ของเขา ทั้งเมเยอร์และต่อมาปิแอร์ อเมริกา ซึ่งเป็นคนแรกที่ใช้คำว่า behavioral subtyping ได้ให้ คำจำกัดความ เชิงทฤษฎี...

การละเมิด

หลักการแทนที่ของ Liskov อธิบายคุณสมบัติว่า "ถ้าสำหรับวัตถุแต่ละประเภทจะมีวัตถุประเภทที่สำหรับโปรแกรมทั้งหมดที่กำหนดตามเงื่อนไขของพฤติกรรมของจะไม่เปลี่ยนแปลงเมื่อแทนที่ด้วยแล้วจะเป็นชนิดย่อย o 1 S o 2 T P T P o 1 o 2 S T ของ " [ 3 ]