Coding tidak sulit sebenarnya . Bagian yang sulit adalah menulis kode yang masuk akal, dapat dibaca dan dimengerti. Jadi saya ingin mendapatkan pengembang yang lebih baik dan membuat arsitektur yang solid.
Jadi saya ingin membuat arsitektur untuk NPC dalam video-game. Ini adalah game Strategi Realtime seperti Starcraft, Age of Empires, Command & Conquers, dll. Jadi saya akan memiliki berbagai jenis NPC. Sebuah NPC dapat memiliki satu ke banyak kemampuan (metode) ini: Build()
, Farm()
dan Attack()
.
Contoh:
Pekerja bisa Build()
dan Farm()
prajurit bisa Attack()
Citizen bisa Build()
, Farm()
dan Attack()
Nelayan bisa Farm()
danAttack()
Saya harap semuanya jelas sejauh ini.
Jadi sekarang saya memiliki Jenis NPC saya dan kemampuan mereka. Tetapi mari kita sampai pada aspek teknis / programatik.
Apa yang akan menjadi arsitektur programatik yang baik untuk berbagai jenis NPC saya?
Oke saya bisa punya kelas dasar. Sebenarnya saya pikir ini adalah cara yang baik untuk tetap berpegang pada prinsip KERING . Jadi saya dapat memiliki metode seperti WalkTo(x,y)
di kelas dasar saya karena setiap NPC akan dapat bergerak. Tapi sekarang mari kita datang ke masalah sebenarnya. Di mana saya menerapkan kemampuan saya? (ingat: Build()
, Farm()
dan Attack()
)
Karena kemampuan akan terdiri dari logika yang sama itu akan mengganggu / mematahkan prinsip KERING untuk mengimplementasikannya untuk setiap NPC (Worker, Warrior, ..).
Oke saya bisa menerapkan kemampuan dalam kelas dasar. Ini akan membutuhkan semacam logika yang memverifikasi jika NPC dapat menggunakan kemampuan X IsBuilder
. CanBuild
,, .. Saya pikir jelas apa yang ingin saya ungkapkan.
Tapi saya merasa tidak enak dengan ide ini. Ini terdengar seperti kelas dasar yang membengkak dengan terlalu banyak fungsi.
Saya menggunakan C # sebagai bahasa pemrograman. Jadi pewarisan berganda bukan pilihan di sini. Berarti: Memiliki kelas dasar tambahan seperti Fisherman : Farmer, Attacker
tidak akan berhasil.
sumber
Jawaban:
Warisan dan Komposisi Antarmuka adalah alternatif biasa untuk pewarisan berganda klasik.
Segala sesuatu yang Anda jelaskan di atas yang dimulai dengan kata "bisa" adalah kemampuan yang dapat direpresentasikan dengan antarmuka, seperti dalam
ICanBuild
, atauICanFarm
. Anda dapat mewarisi sebanyak mungkin antarmuka yang Anda butuhkan.Anda dapat melewati objek bangunan dan pertanian "generik" melalui konstruktor kelas Anda. Di situlah komposisi masuk.
sumber
ICanBuild
. Bahwa Anda juga memiliki alat untuk membangun adalah perhatian sekunder dalam hierarki objek.Seperti poster lain yang menyebutkan arsitektur komponen bisa menjadi solusi untuk masalah ini.
Dalam hal ini memperluas fungsi pembaruan untuk mengimplementasikan fungsi apa pun yang seharusnya dimiliki NPC.
Iterasi wadah komponen dan memperbarui setiap komponen memungkinkan fungsi spesifik dari masing-masing komponen untuk diterapkan.
Karena setiap jenis objek diinginkan, Anda dapat menggunakan beberapa bentuk pola pabrik untuk membangun tipe individu yang Anda inginkan.
Saya selalu mengalami masalah karena komponen semakin kompleks. Menjaga kompleksitas komponen tetap rendah (satu tanggung jawab) dapat membantu meringankan masalah itu.
sumber
Jika Anda mendefinisikan antarmuka seperti itu
ICanBuild
maka sistem game Anda harus memeriksa setiap NPC berdasarkan jenis, yang biasanya disukai OOP. Sebagai contoh:if (npc is ICanBuild)
.Anda lebih baik dengan:
Kemudian:
... atau tentu saja Anda dapat menggunakan sejumlah arsitektur yang berbeda, seperti beberapa jenis bahasa khusus domain dalam bentuk antarmuka yang lancar untuk mendefinisikan berbagai jenis NPC, dll., di mana Anda membangun jenis NPC dengan menggabungkan perilaku yang berbeda:
Pembangun NPC dapat mengimplementasikan
DefaultWalkBehavior
yang bisa diganti dalam kasus NPC yang terbang tetapi tidak bisa berjalan, dll.sumber
if(npc is ICanBuild)
danif(npc.CanBuild)
. Bahkan ketika saya lebih sukanpc.CanBuild
jalan dari sikap saya saat ini.Saya akan menempatkan semua kemampuan dalam kelas terpisah yang mewarisi dari Kemampuan. Kemudian di kelas tipe unit memiliki daftar kemampuan dan hal-hal lain seperti serangan, pertahanan, kesehatan maksimum dll. Juga memiliki kelas unit yang memiliki kesehatan saat ini, lokasi, dll. Dan memiliki tipe unit sebagai variabel anggota.
Tentukan semua tipe unit dalam file konfigurasi atau database, daripada pengkodean keras.
Kemudian desainer level dapat dengan mudah menyesuaikan kemampuan dan statistik dari tipe unit tanpa mengkompilasi ulang game, dan juga orang dapat menulis mod untuk game.
sumber