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 Wizard
kelas 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 Command
s dan menurut Rule
s:
... kami membuat
Command
objek bernamaWield
yang membutuhkan dua objek kondisi permainan, aPlayer
dan aWeapon
. Ketika pengguna mengeluarkan perintah ke sistem "wizard ini harus menggunakan pedang itu", maka perintah itu dievaluasi dalam konteks seperangkatRule
s, yang menghasilkan urutanEffect
s. Kami memiliki satuRule
yang 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 Commands
dan Rule
s dengan hanya mengatur Weapon
pada a Player
. The Weapon
properti perlu diakses oleh Wield
perintah, sehingga tidak dapat dibuat private set
.
Jadi, apa yang dilakukannya mencegah pengembang dari melakukan hal ini? Apakah mereka hanya perlu ingat untuk tidak melakukannya?