Tugasnya adalah mengkonfigurasi perangkat keras di dalam perangkat, sesuai dengan beberapa spesifikasi input. Ini harus dicapai sebagai berikut:
1) Kumpulkan informasi konfigurasi. Ini dapat terjadi di waktu dan tempat yang berbeda. Sebagai contoh, modul A dan modul B dapat meminta (pada waktu yang berbeda) beberapa sumber daya dari modul saya. 'Sumber daya' itu sebenarnya adalah konfigurasi.
2) Setelah jelas bahwa tidak ada lagi permintaan yang akan direalisasikan, perintah startup, memberikan ringkasan sumber daya yang diminta, perlu dikirim ke perangkat keras.
3) Hanya setelah itu, dapat (dan harus) konfigurasi terperinci dari sumber daya tersebut dilakukan.
4) Juga, hanya setelah 2), dapat (dan harus) melakukan routing sumber daya yang dipilih ke pemanggil yang dinyatakan dapat dilakukan.
Penyebab umum untuk bug, bahkan bagi saya, yang menulis hal itu, salah mengira urutan ini. Konvensi, desain, atau mekanisme penamaan apa yang dapat saya terapkan untuk membuat antarmuka dapat digunakan oleh seseorang yang melihat kode untuk pertama kalinya?
sumber
discovery
atauhandshake
?Jawaban:
Ini adalah desain ulang tetapi Anda dapat mencegah penyalahgunaan banyak API tetapi tidak memiliki metode apa pun yang tidak boleh dipanggil.
Misalnya, bukannya
first you init, then you start, then you stop
Konstruktor Anda
init
adalah objek yang dapat dimulai danstart
membuat sesi yang bisa dihentikan.Tentu saja jika Anda memiliki batasan untuk satu sesi pada satu waktu Anda harus menangani kasus di mana seseorang mencoba untuk membuat satu dengan yang sudah aktif.
Sekarang terapkan teknik itu pada kasus Anda sendiri.
sumber
zlib
danjpeglib
adalah dua contoh yang mengikuti pola ini untuk inisialisasi. Namun, banyak dokumentasi yang diperlukan untuk mengajarkan konsep ini kepada pengembang.Anda dapat meminta metode startup mengembalikan objek yang merupakan parameter yang diperlukan ke konfigurasi:
Bahkan jika Anda
MySession
hanya sebuah struct kosong, ini akan menegakkan melalui keamanan jenis yang tidak adaConfigure()
metode yang dapat dipanggil sebelum startup.sumber
module->GetResource()->Configure(nullptr)
?a, b, c, d
, maka saya bisa mulaia
, dan menggunakannyaMySession
untuk mencoba menggunakanb
sebagai objek yang sudah mulai, sedangkan pada kenyataannya tidak.Membangun Jawaban dari Cashcow - mengapa Anda harus menyajikan Obyek baru kepada pemanggil, ketika Anda bisa menyajikan Antarmuka baru? Rubah-Pola:
Anda juga dapat membiarkan ITerminateable menerapkan IRunnable, jika sesi dapat dijalankan beberapa kali.
Objek Anda:
Dengan cara ini Anda hanya dapat memanggil metode yang tepat, karena Anda hanya memiliki IStartable-Interface di awal dan akan menjalankan () Metode hanya dapat diakses ketika Anda telah memanggil start (); Dari luar terlihat seperti pola dengan beberapa kelas dan Objek, tetapi kelas yang mendasarinya tetap satu kelas, yang selalu direferensikan.
sumber
Ada banyak pendekatan yang valid untuk menyelesaikan masalah Anda. Basile Starynkevitch mengusulkan pendekatan "nol-birokrasi" yang membuat Anda memiliki antarmuka yang sederhana dan mengandalkan programmer yang menggunakan antarmuka dengan tepat. Sementara saya suka pendekatan ini, saya akan menyajikan satu lagi yang memiliki lebih banyak eingineering tetapi memungkinkan kompiler untuk menangkap beberapa kesalahan.
Mengidentifikasi berbagai negara perangkat Anda dapat di, sebagai
Uninitialised
,Started
,Configured
dan sebagainya. Daftarnya harus terbatas.¹Untuk setiap negara, tentukan
struct
holding informasi tambahan yang diperlukan yang relevan dengan negara itu, misalnyaDeviceUninitialised
,DeviceStarted
dan sebagainya.Kemas semua perawatan dalam satu objek di
DeviceStrategy
mana metode menggunakan struktur yang ditentukan dalam 2. sebagai input dan output. Dengan demikian, Anda mungkin memilikiDeviceStarted DeviceStrategy::start (DeviceUninitalised dev)
metode (atau apa pun yang setara mungkin sesuai dengan konvensi proyek Anda).Dengan pendekatan ini, program yang valid harus memanggil beberapa metode dalam urutan yang diberlakukan oleh prototipe metode.
Berbagai negara adalah objek yang tidak terkait, ini karena prinsip substitusi. Jika berguna bagi Anda untuk memiliki struktur ini memiliki leluhur yang sama, ingatlah bahwa pola pengunjung dapat digunakan untuk memulihkan tipe konkret dari instance kelas abstrak.
Sementara saya jelaskan dalam 3.
DeviceStrategy
kelas yang unik , ada situasi di mana Anda mungkin ingin membagi fungsionalitas yang disediakannya di beberapa kelas.Untuk meringkasnya, poin-poin utama dari desain yang saya jelaskan adalah:
Karena prinsip substitusi, objek yang mewakili status perangkat harus berbeda dan tidak memiliki hubungan pewarisan khusus.
Kemas perawatan perangkat di objek pemula daripada objek yang mewakili perangkat itu sendiri, sehingga setiap perangkat atau negara perangkat hanya melihat dirinya sendiri, dan strategi melihat semuanya dan mengekspresikan kemungkinan transisi di antara mereka.
Saya bersumpah bahwa saya pernah melihat deskripsi implementasi klien telnet mengikuti baris-baris ini, tetapi saya tidak dapat menemukannya lagi. Itu akan menjadi referensi yang sangat berguna!
¹: Untuk ini, ikuti intuisi Anda atau temukan kelas metode ekuivalen dalam implementasi aktual Anda untuk relasi “metode₁ ~ metode₂ iff. valid untuk menggunakannya pada objek yang sama ”- dengan asumsi Anda memiliki objek besar yang merangkum semua perawatan pada perangkat Anda. Kedua metode daftar negara memberikan hasil yang fantastis.
sumber
Gunakan pola pembangun.
Memiliki objek yang memiliki metode untuk semua operasi yang Anda sebutkan di atas. Namun, itu tidak melakukan operasi ini segera. Itu hanya mengingat setiap operasi untuk nanti. Karena operasi tidak dijalankan segera, urutan di mana Anda meneruskannya ke pembangun tidak masalah.
Setelah Anda mendefinisikan semua operasi pada pembangun, Anda memanggil
execute
-metode. Ketika metode ini dipanggil, ia melakukan semua langkah yang Anda sebutkan di atas dalam urutan yang benar dengan operasi yang Anda simpan di atas. Metode ini juga merupakan tempat yang baik untuk melakukan beberapa pemeriksaan kewarasan rentang operasi (seperti mencoba mengkonfigurasi sumber daya yang belum diatur) sebelum menulisnya ke perangkat keras. Ini dapat menyelamatkan Anda dari kerusakan perangkat keras dengan konfigurasi yang tidak masuk akal (jika perangkat keras Anda rentan terhadap hal ini).sumber
Anda hanya perlu mendokumentasikan dengan benar bagaimana antarmuka digunakan, dan memberikan contoh tutorial.
Anda juga mungkin memiliki varian pustaka debugging yang melakukan beberapa pemeriksaan runtime.
Mungkin mendefinisikan dan mendokumentasikan dengan benar beberapa konvensi penamaan (misalnya
preconfigure*
,startup*
,postconfigure*
,run*
....)BTW, banyak antarmuka yang ada mengikuti pola yang sama (misalnya toolkit X11).
sumber
Ini memang jenis kesalahan yang umum dan berbahaya, karena kompiler hanya dapat menegakkan kondisi sintaks, sementara Anda membutuhkan program klien Anda untuk menjadi "secara tata bahasa" yang benar.
Sayangnya, konvensi penamaan hampir seluruhnya tidak efektif terhadap kesalahan semacam ini. Jika Anda benar-benar ingin mendorong orang untuk tidak melakukan hal-hal yang tidak sesuai tata ruang, Anda harus membagikan objek perintah yang harus diinisialisasi dengan nilai-nilai untuk prasyarat, sehingga mereka tidak dapat melakukan langkah-langkah yang tidak sesuai dengan aturan.
sumber
Dengan menggunakan pola ini, Anda yakin bahwa setiap implementor akan mengeksekusi dalam urutan yang tepat ini. Anda dapat melangkah lebih jauh dan membuat ExecutorFactory yang akan membangun Executor dengan jalur eksekusi kustom.
sumber
step1(); step2(); step3();
. Titik pembangun langkah adalah untuk memberikan API yang memaparkan beberapa langkah, dan untuk menegakkan urutan di mana mereka dipanggil. Seharusnya tidak mencegah programmer melakukan hal-hal lain di antara langkah-langkah.