Bu blog gönderileri dizisinde Eric Lippert, sihirbazları ve savaşçıları kullanarak nesne odaklı tasarımda bir sorunu şöyle açıklıyor:
abstract class Weapon { }
sealed class Staff : Weapon { }
sealed class Sword : Weapon { }
abstract class Player
{
public Weapon Weapon { get; set; }
}
sealed class Wizard : Player { }
sealed class Warrior : Player { }
ve sonra birkaç kural ekler:
- Bir savaşçı sadece kılıç kullanabilir.
- Bir sihirbaz yalnızca bir personel kullanabilir.
Daha sonra, C # tipi sistemi kullanarak bu kuralları uygulamaya çalıştığınızda karşılaştığınız sorunları göstermeye devam eder (örneğin Wizard
, bir sihirbazın yalnızca bir personel kullanabileceğinden emin olmak için sınıfı sorumlu tutmak ). Liskov İkame İlkesini ihlal edersiniz, çalışma zamanı istisnalarını riske eder veya uzatılması zor olan kodlarla sonuçlanırsınız.
Ortaya koyduğu çözüm, Player sınıfı tarafından hiçbir doğrulama yapılmamasıdır. Yalnızca durumu izlemek için kullanılır. Sonra, bir oyuncuya şu silahı vermek yerine:
player.Weapon = new Sword();
durumu Command
s ile değiştirilir ve s'ye göre Rule
:
... a ve a olmak üzere iki oyun durumu nesnesi alan bir
Command
nesne yaparız . Kullanıcı sisteme “bu sihirbaz o kılıcı kullanmalıdır” komutunu verdiğinde, bu komut s dizisi üreten bir s kümesi bağlamında değerlendirilir . Biz bir var bir oyuncu girişimleri silah ellerinde ne zaman, etkisi mevcut silah, eğer varsa, düşürülür ve yeni silah oyuncunun silah haline gelmesi olduğunu söylüyor. Birinci kuralı güçlendiren başka bir kuralımız var, yani bir sihirbaz bir kılıç kullanmaya çalıştığında ilk kuralın etkilerinin geçerli olmadığını söylüyor.Wield
Player
Weapon
Rule
Effect
Rule
Bu fikri prensipte seviyorum, ama pratikte nasıl kullanılabileceğiyle ilgili bir endişem var.
Hiçbir şey atlatabilmesini bir geliştirici önlemek gibi görünüyor Commands
ve Rule
sadece ayarlayarak s Weapon
bir üstünde Player
. Weapon
Mülkiyet tarafından erişilebilir olmalıdır Wield
o yapılamaz bu yüzden, komuta private set
.
Peki, ne yapar bunu bir geliştirici önlemek? Sadece hatırlamamaları gerekiyor mu?