Katakan saya punya:
interface Thing
{
GetThing();
}
class FastThing : Thing
{
public int GetThing()
{
return 1;
}
}
class SlowThing : Thing
{
public int GetThing()
{
return GetThingFromDatabase();
}
}
Apakah ini merupakan pelanggaran terhadap Prinsip Pergantian Liskov?
performance
liskov-substitution
ConditionRacer
sumber
sumber
GetThingFromDatabase()
tidak cukup lambat untuk membuat ini kontroversial.Factor4096BitPublicKey();return 1;
akan membuat hal-hal sedikit lebih menarik.FastThing
denganSlowThing
, LSP tidak berlaku. Jika Anda menambahkan komentarThing::GetThing
yang mengatakan "Sangat cepat", pertanyaannya dapat didiskusikan.Jawaban:
Itu sangat tergantung. Beberapa antarmuka memiliki, misalnya, kendala kompleksitas (ini jelas tidak dapat ditegakkan secara terprogram). Kasus paling mendasar adalah "GetThing () memberikan
int
- yaitu, ia berhenti", dalam hal ini, jawabannya adalah "Tidak" - kedua versi GetThing () berhenti dan kembalikan int.Tetapi banyak antarmuka telah menyiratkan atau secara eksplisit menyatakan jaminan kinerja, baik dalam kompleksitas atau dalam waktu datar. Misalnya, dalam Standar C ++, ilegal untuk mengimplementasikan perpustakaan dengan panggilan pemblokiran kecuali jika Standar secara tegas mengizinkan.
sumber
TL; DR: Tidak
Menurut "Subtyping Perilaku Menggunakan Invarian dan Kendala" (formalisasi prinsip) itu terutama berkaitan dengan sifat "keamanan" dari jenis objek. Properti yang mengatur substitusi hanya dalam konteks tipe informasi. Jenis objek adalah orthogonal untuk kinerjanya. Oleh karena itu perbedaan dalam kinerja bukan merupakan pelanggaran terhadap Prinsip Pergantian Liskov.
sumber
Apa jaminan yang dihasilkan antarmuka? Karena
GetThing
tidak ada jaminan maka subtipe tidak perlu menghormatinya.Jika antarmuka adalah sesuatu seperti
GetThingInLinearTime
atau jika tipe dasar adalah virtual dan implementasi standar adalah satu kompleksitas, maka membuat kompleksitas algoritme yang lebih buruk akan melanggar LSP.sumber
Kinerja perangkat lunak tidak ada hubungannya dengan Prinsip Substitusi Liskov.
Prinsipnya ada hubungannya dengan subtipe, dan dampak perilaku dari mengganti objek itu hanya dalam istilah OOP.
Input dan output
getThing()
tetap sama untuk kedua kasus, dan keduanya lambat dan cepat cenderung menempatkan objek dalam keadaan yang sama.sumber
Apakah penting apa yang dikatakan Prinsip Substitusi Liskov itu sendiri? Jika subtipe melanggar harapan konsumen dari supertipe, itu sepertinya hal yang buruk terlepas dari apakah LSP lebih ketat.
Jadi dalam pandangan saya, apakah semua harapan yang masuk akal dari pengguna sebuah abstraksi dipenuhi oleh subtipe tampaknya menjadi generalisasi yang baik dari LSP.
Namun, dalam contoh Anda telah memposting dan dengan antarmuka Java secara umum, tidak jelas bahwa pengguna
Thing
antarmuka memiliki harapan yang masuk akal apakah harus cepat atau lambat. Jika javadocs antarmuka menyertakan bahasa tentang operasi apa yang dijanjikan akan cepat, maka mungkin ada argumen untuk masalah dengan alasan kinerja. Tetapi konvensi Java tentu untuk berbagai implementasi memiliki karakteristik kinerja yang berbeda.sumber
Paman Bob menjawab pertanyaan yang sangat mirip di mana ia menyatakan bahwa pelanggaran LSP membutuhkan 3 pihak:
Saya berani menebak bahwa pertanyaan ini memiliki struktur yang sama dengan yang dia jawab, dalam hal itu tidak menyebutkan P yang menggunakan T dan perilaku apa yang diharapkan P.
Anda dapat menemukan jawabannya di sini . (Anda harus menggulir ke bawah dan mencari jawaban dari pengguna bernama Robert Martin)
sumber