Saya baru-baru ini mengalami situasi berikut.
class A{
public:
void calculate(T inputs);
}
Pertama, A
merepresentasikan objek di dunia fisik, yang merupakan argumen kuat untuk tidak memisahkan kelas. Sekarang, calculate()
ternyata fungsinya cukup panjang dan rumit. Saya merasakan tiga kemungkinan struktur untuk itu:
- tulis itu sebagai dinding teks - keuntungan - semua informasi ada di satu tempat
- menulis
private
fungsi utilitas di kelas dan menggunakannya dalamcalculate
tubuh - kerugian - seluruh kelas tidak tahu / tidak peduli / mengerti tentang metode-metode itu tulis
calculate
cara berikut:void A::calculate(T inputs){ auto lambda1 = () [] {}; auto lambda2 = () [] {}; auto lambda3 = () [] {}; lambda1(inputs.first_logical_chunk); lambda2(inputs.second_logical_chunk); lambda3(inputs.third_logical_chunk); }
Bisakah ini dianggap sebagai praktik yang baik atau buruk? Apakah pendekatan ini mengungkapkan masalah? Secara keseluruhan, haruskah saya menganggap ini sebagai pendekatan yang baik ketika saya dihadapkan pada situasi yang sama?
EDIT:
class A{
...
public:
// Reconfiguration of the algorithm.
void set_colour(double colour);
void set_density(double density);
void set_predelay(unsigned long microseconds);
void set_reverb_time(double reverb_time, double room_size);
void set_drywet(double left, double right);
void set_room_size(double value);;
private:
// Sub-model objects.
...
}
Semua metode itu:
- dapatkan nilai
- menghitung beberapa nilai lain, tanpa menggunakan status
- panggil beberapa "objek sub-model" untuk mengubah statusnya.
Ternyata, kecuali set_room_size()
, metode-metode itu hanya meneruskan nilai yang diminta ke sub-objek. set_room_size()
, di sisi lain, melakukan beberapa layar formula yang tidak jelas dan kemudian (2) melakukan setengah layar memanggil sub-objek setter untuk menerapkan berbagai hasil yang diperoleh. Karena itu, saya telah memisahkan fungsi menjadi dua lambda dan memanggil mereka di akhir fungsi. Seandainya saya bisa membaginya menjadi potongan yang lebih logis, saya akan mengisolasi lebih banyak lambda.
Terlepas dari itu, tujuan dari pertanyaan saat ini adalah untuk menentukan apakah cara berpikir itu harus bertahan, atau apakah yang terbaik tidak menambah nilai (keterbacaan, pemeliharaan, kemampuan debug dll).
Firstly, A represents an object in the physical world, which is a strong argument for not splitting the class up.
TentunyaA
merepresentasikan data tentang suatu objek yang bisa eksis di dunia fisik. Anda dapat memiliki instanceA
tanpa objek nyata dan objek nyata tanpa instanceA
, jadi memperlakukan mereka seolah-olah satu dan yang sama tidak masuk akal.calculate()
tahu tentang sub-fungsi tersebut.A
, itu agak berlebihan.A
mewakili sebuah objek di dunia fisik, yang merupakan argumen kuat untuk tidak memisahkan kelas." Sayangnya, saya diberitahu hal ini ketika saya mulai pemrograman. Butuh bertahun-tahun bagiku untuk menyadari bahwa itu adalah sekelompok hoki kuda. Ini alasan mengerikan untuk mengelompokkan berbagai hal. Saya tidak bisa mengartikulasikan apa yang alasan yang baik untuk hal-hal kelompok (setidaknya untuk kepuasan saya), tapi satu yang adalah salah satu Anda harus membuang sekarang. Pada akhirnya, semua "kode yang baik" adalah berfungsi dengan baik, relatif mudah dipahami, dan relatif mudah diubah (yaitu, perubahan tidak memiliki efek samping yang aneh).Jawaban:
Tidak, ini umumnya bukan pola yang baik
Apa yang Anda lakukan adalah memecah suatu fungsi menjadi fungsi yang lebih kecil menggunakan lambda. Namun, ada alat yang jauh lebih baik untuk memecah fungsi: fungsi.
Lambdas bekerja, seperti yang telah Anda lihat, tetapi artinya jauh lebih dari sekadar memecah fungsi menjadi bit lokal. Lambdas lakukan:
Begitu Anda membawa lambdas ke dalam campuran, pengembang berikutnya untuk melihat kode harus segera memuat semua aturan secara mental dalam persiapan untuk melihat bagaimana kode Anda bekerja. Mereka tidak tahu bahwa Anda tidak akan menggunakan semua fungsi itu. Ini sangat mahal, dibandingkan dengan alternatifnya.
Ini seperti menggunakan cangkul belakang untuk berkebun. Anda tahu bahwa Anda hanya menggunakannya untuk menggali lubang kecil untuk bunga tahun ini, tetapi tetangga akan merasa gugup.
Pertimbangkan bahwa semua yang Anda lakukan adalah mengelompokkan kode sumber Anda secara visual. Kompiler tidak benar-benar peduli bahwa Anda menjilat sesuatu dengan lambdas. Bahkan, saya berharap pengoptimal untuk segera membatalkan semua yang baru saja Anda lakukan ketika dikompilasi. Anda murni melayani pembaca berikutnya (Terima kasih telah melakukan itu, bahkan jika kami tidak setuju pada metodologi! Kode dibaca jauh lebih sering daripada yang ditulis!). Yang Anda lakukan hanyalah fungsi pengelompokan.
// ------------------
antara setiap bagian.EDIT: Dari melihat hasil edit Anda dengan kode contoh, saya condong ke arah notasi komentar yang paling bersih, dengan tanda kurung untuk menegakkan batas yang disarankan komentar. Namun, jika ada fungsi yang dapat digunakan kembali di fungsi lain, saya akan merekomendasikan menggunakan fungsi saja
sumber
count++
)calculate()
menjadi{}
blok dan mendeklarasikan data bersama dicalculate()
ruang lingkup. Saya berpikir bahwa dengan melihat bahwa lambda tidak menangkap, pembaca tidak akan terbebani oleh kekuatan lambda.lambda
tidak adil, atau jika Anda dengan kasar memaksa orang untuk mengikuti denotasi yang ketat, bukanlah pertanyaan yang mudah dijawab. Bahkan, mungkin bisa sepenuhnya diterima bagi Anda untuk menggunakanlambda
cara itu di perusahaan Anda, dan sama sekali tidak dapat diterima di perusahaan saya, dan tidak ada yang benar-benar salah!lambda
, sepertifor_each
fungsi. Karena itu, ketika saya melihat sebuahlambda
yang tidak cocok dengan salah satu kasus kesulitan yang mudah dikenali, asumsi pertama yang saya dapatkan adalah bahwa itu kemungkinan akan digunakan untuk pemrograman fungsional, karena itu tidak diperlukan sebaliknya. Bagi banyak pengembang, pemrograman fungsional adalah pola pikir yang sama sekali berbeda dari pemrograman prosedural atau OO.Saya pikir Anda membuat asumsi yang buruk:
Saya tidak setuju dengan ini. Misalnya, jika saya memiliki kelas yang mewakili mobil, saya pasti ingin membaginya, karena saya pasti ingin kelas yang lebih kecil untuk mewakili ban.
Anda harus membagi fungsi ini menjadi fungsi pribadi yang lebih kecil. Jika benar-benar tampak terpisah dari bagian lain dari kelas, maka itu mungkin merupakan tanda bahwa kelas harus dipisahkan. Tentu saja sulit untuk mengatakannya tanpa contoh eksplisit.
Saya tidak benar-benar melihat keuntungan dari menggunakan fungsi lambda dalam kasus ini, karena itu tidak benar-benar membuat kode lebih bersih. Mereka diciptakan untuk membantu pemrograman gaya fungsional, tetapi ini bukan itu.
Apa yang Anda tulis sedikit mirip dengan objek fungsi bersarang gaya Javascript. Yang lagi-lagi merupakan pertanda bahwa mereka memiliki kedekatan. Apakah Anda yakin, bahwa Anda tidak boleh membuat kelas yang terpisah untuk mereka?
Singkatnya, saya tidak berpikir bahwa ini adalah pola yang baik.
MEMPERBARUI
Jika Anda tidak melihat cara apa pun untuk merangkum fungsi ini dalam kelas yang bermakna, maka Anda bisa membuat fungsi pembantu lingkup file, yang bukan anggota kelas Anda. Bagaimanapun ini adalah C ++, desain OO tidak harus.
sumber
A
(bahkan mungkin functor dengan semua metode lain pribadi)? Kelas dideklarasikan dan didefinisikan di dalamcalculate()
(ini sangat mirip dengan contoh lambda saya). Sebagai klarifikasi,calculate()
adalah satu dari sekumpulan metode (calculate_1(), calculate_2()
dll.) Yang semuanya sederhana, hanya saja ini adalah 2 layar formula.calculate()
jauh lebih lama daripada semua metode lainnya?