การกวดวิชา

หลักการของการแทนที่ Liskov หลักการ SOLID ที่สาม

คลาสลูกไม่ควรมีผลกระทบหรือแก้ไขไฟล์ defiคำสั่งประเภทของคลาสพาเรนต์

แนวคิดของหลักการนี้ได้รับการแนะนำโดย Barbara Liskov ในการปราศรัยของการประชุมในปี 1987 และต่อมาได้ตีพิมพ์ในเอกสารร่วมกับ Jannette Wing ในปี 1994 defiต้นฉบับมีดังนี้:

ให้ q (x) เป็นคุณสมบัติที่พิสูจน์ได้บนอ็อบเจกต์ x ของประเภท T จากนั้น q (y) ควรสามารถพิสูจน์ได้สำหรับอ็อบเจ็กต์ y ประเภท S โดยที่ S เป็นประเภทย่อยของ T.

ต่อจากนั้น ด้วยการตีพิมพ์หลักการ SOLID ของ Robert C. Martin ในหนังสือ Agile Software Development, Principles, Patterns, and Practices ของเขา และตีพิมพ์ซ้ำในหนังสือ Agile Principles, Patterns, and Practices in C# เวอร์ชัน C# defiกลายเป็นที่รู้จักในชื่อหลักการทดแทนของลิสคอฟ

สิ่งนี้นำเราไปสู่ defiข้อมูลที่ได้รับจาก Robert C. Martin: ต้องเปลี่ยนประเภทย่อยด้วยประเภทพื้นฐาน

ยิ่งไปกว่านั้นคลาสย่อยจะต้องแทนที่เมธอดของคลาสพาเรนต์ด้วยวิธีที่ไม่ทำลายฟังก์ชันการทำงานจากมุมมองของลูกค้า นี่คือตัวอย่างง่ายๆเพื่อแสดงแนวคิด

คลาสรถ {

    ฟังก์ชัน startEngine () {

        // ฟังก์ชันสตาร์ทเครื่องยนต์เริ่มต้น

    }

 

    ฟังก์ชันเร่ง () {

        // ฟังก์ชันการเร่งความเร็วเริ่มต้น

    }

}

ระบุคลาสยานพาหนะ - อาจเป็นนามธรรม - และการใช้งานสองแบบ:

class Car ขยายยานพาหนะ {

    ฟังก์ชัน startEngine () {

        $ this-> EngagementIgnition ();

        ผู้ปกครอง :: startEngine ();

    }

 

    ฟังก์ชันส่วนตัว EngagementIgnition () {

        // ขั้นตอนการจุดระเบิด

    }

}

 

คลาส ElectricBus ขยายยานพาหนะ {

    ฟังก์ชันเร่ง () {

        $ this-> เพิ่มแรงดันไฟฟ้า ();

        $ this-> connectIndividualEngines ();

    }

 

    ฟังก์ชั่นส่วนตัวเพิ่มแรงดันไฟฟ้า () {

        // ลอจิกไฟฟ้า

    }

 

    ฟังก์ชั่นส่วนตัว connectIndividualEngines () {

        // ตรรกะการเชื่อมต่อ

    }

}

คลาสไดร์เวอร์ {

    function go (Vehicle $ v) {

        $ v-> startEngine ();

        $ v-> เร่ง ();

    }

}

คลาสไคลเอนต์ควรสามารถใช้ได้ทั้งสองอย่างหากสามารถใช้ยานพาหนะได้

ซึ่งนำเราไปสู่การใช้งาน Template Method Design Pattern อย่างง่ายๆเหมือนที่เราใช้ใน OCP

คุณอาจสนใจหลักการ SOLID ที่สอง: https: //bloginnovazione.th / open-closed-second-solid-principle / 3906 /

จากประสบการณ์ก่อนหน้านี้ของเราเกี่ยวกับหลักการเปิด / ปิดเราสามารถสรุปได้ว่าหลักการแทนที่ Liskov เกี่ยวข้องอย่างใกล้ชิดกับ OCP ในความเป็นจริง "การละเมิด LSP เป็นการละเมิด OCP แบบแฝง" (Robert C. Martin) และรูปแบบวิธีการออกแบบเทมเพลตเป็นตัวอย่างคลาสสิกของการเคารพและการใช้งาน LSP ซึ่งจะเป็นหนึ่งในวิธีแก้ปัญหา ด้วย OCP

ตัวอย่างการละเมิด LSP

คลาสสี่เหลี่ยมผืนผ้า {

    ส่วนตัว $ topLeft;

    ความกว้าง $ ส่วนตัว;

    ส่วนตัว $ สูง;

 

    ฟังก์ชันสาธารณะ setHeight ($ height) {

        $ this-> height = $ height;

    }

 

จดหมายข่าวนวัตกรรม
อย่าพลาดข่าวสารที่สำคัญที่สุดเกี่ยวกับนวัตกรรม ลงทะเบียนเพื่อรับพวกเขาทางอีเมล

    ฟังก์ชันสาธารณะ getHeight () {

        กลับ $ this-> height;

    }

 

    ฟังก์ชันสาธารณะ setWidth ($ width) {

        $ this-> width = $ width;

    }

 

    ฟังก์ชันสาธารณะ getWidth () {

        คืนค่า $ this-> width;

    }

}

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

ในชีวิตจริงในรูปทรงเรขาคณิตสี่เหลี่ยมจัตุรัสคือรูปทรงเฉพาะของสี่เหลี่ยมผืนผ้า เราสามารถลองใช้คลาส Square ที่ขยายคลาส Rectangle มักกล่าวกันว่าคลาสลูกเป็นคลาสแม่และนิพจน์นี้ยังสอดคล้องกับ LSP อย่างน้อยก็ในตอนแรก

class Square ขยาย Rectangle {

    ฟังก์ชันสาธารณะ setHeight ($ value) {

        $ this-> width = $ value;

        $ this-> height = $ value;

    }

 

    ฟังก์ชันสาธารณะ setWidth ($ value) {

        $ this-> width = $ value;

        $ this-> height = $ value;

    }

}

สี่เหลี่ยมจัตุรัสคือสี่เหลี่ยมผืนผ้าที่มีความกว้างและความสูงเท่ากันและเราสามารถใช้งานแปลก ๆ ได้เหมือนในตัวอย่างก่อนหน้านี้ เราสามารถแทนที่ตัวตั้งค่าทั้งสองเพื่อกำหนดทั้งความสูงและความกว้าง แต่สิ่งนี้จะส่งผลต่อรหัสไคลเอนต์อย่างไร?

คลาสไคลเอนต์ {

    function areaVerifier (สี่เหลี่ยมผืนผ้า $ r) {

        $ r-> setWidth (5);

        $ r-> setHeight (4);

        ถ้า ($ r-> area ()! = 20) {

            โยนข้อยกเว้นใหม่ ('พื้นที่ไม่ดี!');

        }

        กลับจริง

    }

}

เป็นไปได้ที่จะมีคลาสไคลเอ็นต์ที่ตรวจสอบพื้นที่ของสี่เหลี่ยมผืนผ้าและแสดงข้อยกเว้นหากผิด

พื้นที่ฟังก์ชัน () {

    ส่งคืน $ this-> width * $ this-> height;

}

เห็นได้ชัดว่าเราได้เพิ่มวิธีการข้างต้นในคลาส Rectangle ของเราเพื่อให้มีพื้นที่

คลาส LspTest ขยาย PHPUnit_Framework_TestCase {

    ฟังก์ชัน testRectangleArea () {

        $ r = สี่เหลี่ยมผืนผ้าใหม่ ();

        $ c = ลูกค้าใหม่ ();

        $ this-> assertTrue ($ c-> areaVerifier ($ r));

    }

}

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

ฟังก์ชัน testSquareArea () {

    $ r = สแควร์ใหม่ ();

    $ c = ลูกค้าใหม่ ();

    $ this-> assertTrue ($ c-> areaVerifier ($ r));

}

ดังนั้นคลาส Square ของเราจึงไม่ใช่สี่เหลี่ยมผืนผ้า มันฝ่าฝืนกฎแห่งเรขาคณิต มันล้มเหลวและละเมิดหลักการทดแทน Liskov.

Ercole Palmeri

จดหมายข่าวนวัตกรรม
อย่าพลาดข่าวสารที่สำคัญที่สุดเกี่ยวกับนวัตกรรม ลงทะเบียนเพื่อรับพวกเขาทางอีเมล

บทความล่าสุด

ประโยชน์ของการระบายสีหน้าสำหรับเด็ก - โลกแห่งเวทมนตร์สำหรับทุกวัย

การพัฒนาทักษะยนต์ปรับผ่านการระบายสีจะช่วยเตรียมเด็กๆ ให้พร้อมสำหรับทักษะที่ซับซ้อนมากขึ้น เช่น การเขียน หากต้องการสี...

2 2024 พ.ค.

อนาคตอยู่ที่นี่: อุตสาหกรรมการขนส่งกำลังปฏิวัติเศรษฐกิจโลกอย่างไร

ภาคกองทัพเรือเป็นมหาอำนาจทางเศรษฐกิจระดับโลกอย่างแท้จริง ซึ่งได้มุ่งหน้าสู่ตลาดมูลค่า 150 พันล้าน...

1 2024 พ.ค.

ผู้จัดพิมพ์และ OpenAI ลงนามข้อตกลงเพื่อควบคุมการไหลของข้อมูลที่ประมวลผลโดยปัญญาประดิษฐ์

เมื่อวันจันทร์ที่แล้ว Financial Times ได้ประกาศข้อตกลงกับ OpenAI FT อนุญาติให้ทำข่าวระดับโลก...

30 2024 เมษายน

การชำระเงินออนไลน์: นี่คือวิธีที่บริการสตรีมมิ่งทำให้คุณชำระเงินตลอดไป

ผู้คนนับล้านชำระค่าบริการสตรีมมิ่ง โดยจ่ายค่าธรรมเนียมการสมัครสมาชิกรายเดือน เป็นความเห็นทั่วไปที่คุณ...

29 2024 เมษายน

อ่านนวัตกรรมในภาษาของคุณ

จดหมายข่าวนวัตกรรม
อย่าพลาดข่าวสารที่สำคัญที่สุดเกี่ยวกับนวัตกรรม ลงทะเบียนเพื่อรับพวกเขาทางอีเมล

ติดตามเรา