Dalam seri posting blog ini , Eric Lippert menjelaskan masalah dalam desain berorientasi objek menggunakan penyihir dan prajurit sebagai contoh, di mana:
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 { }
dan kemudian menambahkan beberapa aturan:
- Seorang prajurit hanya bisa menggunakan pedang.
- Seorang penyihir hanya bisa menggunakan staf.
Dia kemudian melanjutkan untuk mendemonstrasikan masalah yang Anda hadapi jika Anda mencoba untuk menegakkan aturan-aturan ini menggunakan sistem tipe C # (misalnya membuat Wizardkelas bertanggung jawab untuk memastikan bahwa seorang penyihir hanya dapat menggunakan staf). Anda melanggar Prinsip Substitusi Liskov, mengambil risiko pengecualian waktu berjalan atau berakhir dengan kode yang sulit diperpanjang.
Solusi yang ia temukan adalah tidak ada validasi yang dilakukan oleh kelas Player. Ini hanya digunakan untuk melacak status. Kemudian, alih-alih memberikan senjata kepada pemain dengan:
player.Weapon = new Sword();
negara diubah oleh Commands dan menurut Rules:
... kami membuat
Commandobjek bernamaWieldyang membutuhkan dua objek kondisi permainan, aPlayerdan aWeapon. Ketika pengguna mengeluarkan perintah ke sistem "wizard ini harus menggunakan pedang itu", maka perintah itu dievaluasi dalam konteks seperangkatRules, yang menghasilkan urutanEffects. Kami memiliki satuRuleyang mengatakan bahwa ketika seorang pemain mencoba untuk menggunakan senjata, efeknya adalah bahwa senjata yang ada, jika ada, dijatuhkan dan senjata baru menjadi senjata pemain. Kami memiliki aturan lain yang memperkuat aturan pertama, yang mengatakan bahwa efek aturan pertama tidak berlaku ketika seorang penyihir mencoba memegang pedang.
Saya menyukai ide ini pada prinsipnya, tetapi memiliki keprihatinan tentang bagaimana itu dapat digunakan dalam praktik.
Sepertinya tidak ada yang menghalangi pengembang untuk melewati Commandsdan Rules dengan hanya mengatur Weaponpada a Player. The Weaponproperti perlu diakses oleh Wieldperintah, sehingga tidak dapat dibuat private set.
Jadi, apa yang dilakukannya mencegah pengembang dari melakukan hal ini? Apakah mereka hanya perlu ingat untuk tidak melakukannya?