Domain pengetahuan kami melibatkan orang-orang yang berjalan di atas piring penekan tekanan dengan kaki telanjang. Kami melakukan pengenalan gambar yang menghasilkan objek dari kelas 'Kaki', jika kaki manusia dikenali dalam data sensor.
Ada beberapa perhitungan yang harus dilakukan pada data kaki.
Sekarang, API mana yang lebih baik:
class Foot : public RecognizedObject {
MaxPressureFrame getMaxPressureFrame();
FootAxis getFootAxis();
AnatomicalZones getAnatomicalZones();
// + similar getters for other calculations
// ...
}
Atau:
class Foot : public RecognizedObject {
virtual CalculationBase getCalculation(QString aName);
// ...
}
Sekarang, ada banyak pro dan kontra yang bisa saya buat, tapi saya tidak bisa memutuskan mana yang paling penting. Catatan, ini adalah aplikasi pengguna akhir, bukan perpustakaan perangkat lunak yang kami jual.
Ada saran?
Beberapa pro untuk pendekatan pertama dapat:
- CIUMAN - semuanya sangat konkret. API, tetapi implementasinya juga.
- nilai pengembalian sangat diketik.
- mewarisi dari kelas ini adalah bukti bodoh. Tidak ada yang bisa ditimpa, hanya ditambahkan.
- API sangat tertutup, tidak ada yang masuk, tidak ada yang bisa ditimpa, jadi lebih sedikit yang bisa salah.
Beberapa con:
- Jumlah getter akan bertambah, karena setiap perhitungan baru yang kami temukan akan ditambahkan ke daftar
- API lebih cenderung berubah, dan jika memecah perubahan diperkenalkan, kita membutuhkan versi API baru, Foot2.
- dalam hal penggunaan kembali kelas di proyek lain, kita mungkin tidak perlu setiap perhitungan
Beberapa pro untuk pendekatan kedua:
- lebih fleksibel
- api lebih kecil kemungkinannya untuk berubah, (dengan asumsi kita mendapatkan abstraksi yang benar, jika tidak, perubahan akan lebih mahal)
Beberapa con:
- diketik dengan longgar. Membutuhkan gips pada setiap panggilan.
- parameter string - Saya punya firasat buruk tentang itu (bercabang pada nilai string ...)
- Tidak ada use case / persyaratan saat ini yang mengamanatkan fleksibilitas ekstra, tetapi mungkin ada di masa depan.
- API memberlakukan batasan: setiap perhitungan harus berasal dari kelas dasar. Mendapatkan perhitungan akan dipaksa melalui metode 1 ini, dan melewati parameter tambahan tidak akan mungkin, kecuali jika kita merancang cara yang lebih dinamis, super-fleksibel untuk melewatkan parameter yang meningkatkan kompleksitas bahkan lebih.
enum
dan mengaktifkan nilainya. Tetap saja, saya pikir pilihan kedua adalah jahat, karena menyimpang dari KISS.getCalculation()
.Jawaban:
Saya pikir dalam pendekatan pertama akan membuahkan hasil. String ajaib dapat membuat masalah berikut: Kesalahan pengetikan, penyalahgunaan, keamanan jenis pengembalian non-sepele, kurangnya penyelesaian kode, kode tidak jelas (apakah versi ini memiliki fitur itu? Saya kira kita akan mengetahuinya saat runtime). Menggunakan enum akan menyelesaikan beberapa masalah tersebut, tetapi mari kita lihat kontra yang Anda ajukan:
Benar, itu bisa menjengkelkan, tetapi hal itu menjaga hal-hal yang bagus dan ketat, dan memberi Anda penyelesaian kode di mana pun dalam proyek Anda dalam IDE modern apa pun, dengan komentar judul yang baik yang jauh lebih berguna daripada enum.
Benar, tapi itu sebenarnya pro besar;) Anda bisa mendefinisikan antarmuka untuk sebagian API, dan kemudian Anda tidak perlu mengkompilasi ulang kelas dependen yang tidak terpengaruh oleh API yang lebih baru (Jadi tidak perlu untuk Foot2). Itu memungkinkan decoupling yang lebih baik, ketergantungannya sekarang dari antarmuka dan bukan implementasinya. Apalagi jika antarmuka yang ada berubah, Anda akan memiliki kesalahan kompilasi di kelas dependen, yang bagus untuk mencegah kode basi.
Saya tidak melihat bagaimana menggunakan senar ajaib atau enum akan membantu dengan itu ... Jika saya mengerti dengan benar, Anda memasukkan kode di kelas Foot atau Anda memecahnya ke beberapa kelas yang lebih kecil, dan itu berlaku untuk kedua opsi
sumber
IEnumerable<T>.Count
], pendekatan semacam itu memungkinkan kode untuk menikmati manfaat kinerja dari yang baru. fitur antarmuka saat menggunakan implementasi yang mendukungnya, tetapi tetap kompatibel dengan implementasi lama.Saya akan merekomendasikan opsi 3: Jelaskan bahwa perhitungan bukan bagian intrinsik dari abstraksi a
Foot
, tetapi operasikanlah. Kemudian Anda dapat membagiFoot
dan perhitungannya menjadi kelas yang terpisah, seperti ini:Dengan cara ini, Anda masih memiliki pengetikan yang kuat dari perhitungan Anda, dan Anda dapat menambahkan yang baru tanpa memengaruhi kode yang ada (kecuali Anda membuat kesalahan serius dalam jumlah informasi yang diekspos oleh
Foot
).sumber