Son zamanlarda içinde bazı büyük Liskov ihlal edenlerin bulunduğu bir kod temeli miras aldım. Önemli sınıflarda. Bu bana çok fazla acı verdi. Nedenini açıklamama izin ver.
Ben Class A, türetilen var Class B. Class Ave kendi uygulamasıyla geçersiz kılan Class Bbir dizi mülkü paylaşın Class A. Bir Class Amülkün ayarlanması veya elde edilmesi, aynı mülkün ayarlanması veya elde edilmesi üzerinde farklı bir etkiye sahiptir Class B.
public Class A
{
public virtual string Name
{
get; set;
}
}
Class B : A
{
public override string Name
{
get
{
return TranslateName(base.Name);
}
set
{
base.Name = value;
FunctionWithSideEffects();
}
}
}
Bunun .NET'te çeviri yapmak için tamamen berbat bir yol olduğu gerçeğini bir kenara bırakmak gerekirse, bu kodla ilgili başka birçok sorun var.
Bu durumda Name, birçok yerde bir indeks ve bir akış kontrol değişkeni olarak kullanılır. Yukarıdaki sınıflar, kod tabanı boyunca hem ham hem de türetilmiş formları ile doldurulur. Bu durumda Liskov ikame ilkesini ihlal etmek, temel sınıfı alan işlevlerin her birine yapılan her bir çağrının içeriğini bilmem gerektiği anlamına gelir.
Kod her ikisinin nesnelerini kullanır Class Ave Class Bbu yüzden Class Ainsanları kullanmaya zorlamak için soyut yapamam Class B.
Üzerinde çalışan bazı çok faydalı yardımcı işlevler Class Ave üzerinde çalışan diğer çok yararlı yardımcı işlevler vardır Class B. İdeal olarak, Class Aüzerinde çalışabilecek herhangi bir yardımcı işlevi kullanabilmek istiyorum Class B. LSP'nin ihlali için olmasaydı, Class Bbir çok fonksiyonu alan bir şeyi kolayca alabilirdi Class A.
Bununla ilgili en kötü şey, bu uygulamanın bu iki sınıfa dayandığı, her zaman her iki derste de çalıştığı ve yüzlerce şekilde bozulacağı için (ki bunu yapacağım) kırmak için gerçekten zor bir durum. Neyse).
Bunu düzeltmek için yapmam gereken , mülkün sürümü NameTranslatedolacak bir mülk oluşturmak ve yeni mülkümü kullanmak için türetilmiş mülke yapılan tüm referansları çok, çok dikkatli bir şekilde değiştiriyorum . Bununla birlikte, bu referanslardan bir tanesinin yanlış yapılması bile tüm başvuru patlayabilir.Class BNameNameNameTranslated
Kod tabanının çevresinde birim testlerinin bulunmadığı göz önüne alındığında, bu, geliştiricinin karşılaşabileceği en tehlikeli senaryo olmaya oldukça yakın. İhlali değiştirmezsem, her yöntemde ne tür bir nesnenin kullanıldığını takip ederek büyük miktarda zihinsel enerji harcamam gerekir ve ihlali giderirsem ürünün tamamını uygun olmayan bir zamanda patlatabilirim.