Saya sedang mengembangkan aplikasi yang akan digunakan untuk membuka dan menutup katup di lingkungan industri, dan memikirkan sesuatu yang sederhana seperti ini: -
public static void ValveController
{
public static void OpenValve(string valveName)
{
// Implementation to open the valve
}
public static void CloseValve(string valveName)
{
// Implementation to close the valve
}
}
(Implementasi akan menulis beberapa byte data ke port serial untuk mengontrol katup - "alamat" yang berasal dari nama katup, dan "1" atau "0" untuk membuka atau menutup katup).
Pengembang lain bertanya apakah kita harus membuat kelas terpisah untuk setiap katup fisik, yang jumlahnya puluhan. Saya setuju akan lebih baik untuk menulis kode seperti PlasmaValve.Open()
daripada ValveController.OpenValve("plasma")
, tetapi apakah ini berlebihan?
Juga, saya bertanya-tanya bagaimana cara terbaik untuk menangani desain dengan beberapa persyaratan masa depan hipotetis dalam pikiran: -
- Kami diminta untuk mendukung jenis katup baru yang membutuhkan nilai berbeda untuk membuka dan menutupnya (bukan 0 dan 1).
- Kami diminta untuk mendukung katup yang dapat disetel ke posisi apa pun dari 0-100, daripada hanya "terbuka" atau "tertutup".
Biasanya saya akan menggunakan warisan untuk hal semacam ini, tetapi saya baru-baru ini mulai mendapatkan sekitar "komposisi atas warisan" dan bertanya-tanya apakah ada solusi yang lebih licin yang bisa didapat dengan menggunakan komposisi?
sumber
Jawaban:
Jika setiap instance dari objek valve akan menjalankan kode yang sama dengan ValveController ini, maka sepertinya beberapa instance dari satu kelas akan menjadi cara yang tepat. Dalam hal ini, cukup konfigurasikan katup mana yang dikontrolnya (dan bagaimana) di konstruktor objek katup.
Namun jika setiap kontrol katup memerlukan kode yang berbeda untuk dijalankan, dan ValveController saat ini menjalankan pernyataan saklar raksasa yang melakukan hal-hal yang berbeda tergantung pada jenis katup, maka Anda telah menerapkan kembali polimorfisme dengan buruk. Dalam hal itu, tulis ulang ke beberapa kelas dengan basis umum (jika itu masuk akal) dan biarkan prinsip tanggung jawab tunggal menjadi panduan desain Anda.
sumber
Keluhan utama saya adalah menggunakan string untuk parameter yang mengidentifikasi katup.
Setidaknya buat
Valve
kelas yang memilikigetAddress
dalam bentuk kebutuhan implementasi yang mendasarinya dan berikan kepadaValveController
dan pastikan bahwa Anda tidak dapat membuat katup yang tidak ada. Dengan cara ini Anda tidak perlu menangani string yang salah di setiap metode buka dan tutup.Apakah Anda membuat metode kenyamanan yang memanggil buka dan tutup
ValveController
adalah terserah Anda, tetapi jujur saya akan menyimpan semua komunikasi ke port serial (termasuk pengkodean) dalam satu kelas yang akan dipanggil oleh kelas lain bila diperlukan. Ini berarti bahwa ketika Anda perlu bermigrasi ke controller baru Anda hanya perlu memodifikasi satu kelas.Jika Anda menyukai pengujian, Anda juga harus membuat
ValveController
singleton sehingga Anda dapat mengejeknya (atau membuat mesin pelatihan untuk operator).sumber