Buat kelas dan metode saya sekecil mungkin?

20

Beberapa hari yang lalu, saya berbicara dengan kandidat PhD Rekayasa Perangkat Lunak dan pada suatu saat dia berkata kepada saya:

Jaga kelas dan metode Anda sekecil mungkin

Dan saya ingin tahu apakah ini selalu merupakan praktik yang baik.

Maksud saya misalnya, apakah layak untuk memiliki kelas dengan hanya 2 attibutes di dalamnya? Sebagai contoh, Dalam beberapa metode saya perlu pasangan bilangan bulat untuk bekerja dengannya. Haruskah saya menulis kelas "PairOfIntgers"?

Mungkinkah cara berpikir ini "memecah" kode menjadi terlalu banyak?

Florents Tselai
sumber
10
Itu seharusnya"As small as possible, but no smaller."
StuperUser
"Maksudku, misalnya, apakah layak untuk memiliki kelas dengan hanya 2 attibutes di dalamnya?" - Bisa jadi, cari "Obsesi Primitif" (mis. Jamesshore.com/Blog/PrimitiveObsession.html )
Torsten
Saya pikir sumber kebingungan adalah kata "mungkin". Prinsipnya menjadi konyol jika "mungkin" merujuk hanya ke kode, karena kelas sekecil mungkin yang melakukan sesuatu yang bermanfaat hanya memiliki satu metode (dan dalam beberapa kasus nol). Kandidat sangat mungkin dimaksudkan untuk memperhitungkan kohesi dan penggabungan.
Kelvin

Jawaban:

23

Ada butir kebenaran dalam saran itu, tetapi IMHO itu tidak diungkapkan dengan baik, sehingga mudah untuk salah paham dan / atau untuk dibawa ke ekstrem bodoh. Bagaimanapun, ini harus menjadi aturan praktis, bukan hukum keras. Dan Anda harus selalu menyiratkan dalam aturan seperti itu klausa "dalam batas wajar" , atau "tapi jangan lupa untuk menggunakan akal sehat Anda" :-)

Butir kebenaran adalah bahwa dalam praktiknya, kelas dan metode selalu cenderung tumbuh secara alami, bukan menyusut . Perbaikan bug di sini, ekstensi fitur kecil di sana, menangani kasus khusus di sana ... dan voila, kelas Anda yang dulu rapi dan kecil mulai membengkak. Seiring waktu, kode Anda hampir pasti cenderung menjadi kekacauan spageti yang mengerikan - kecuali jika Anda secara aktif melawan kecenderungan ini melalui refactoring . Refactoring hampir selalu menghasilkan banyak kelas / metode yang lebih kecil dari yang besar. Tapi tentu saja, ada batas yang masuk akal untuk miniaturisasi. Inti dari refactoring bukan untuk memiliki kelas dan metode yang lebih kecil, tetapi untuk membuat kode Anda lebih bersih, lebih mudah dipahami dan dipelihara . Pada titik tertentu, membuat metode / kelas Anda lebih kecil mulai mengurangi keterbacaan, bukan meningkatkannya. Arahkan ke arah optimal itu. Ini adalah area target yang buram dan bergerak, jadi Anda tidak perlu memukulnya tepat. Tingkatkan sedikit kode setiap kali Anda melihat ada masalah dengannya .

Péter Török
sumber
1
pasti aturan untuk tidak mengikuti secara membabi buta, terlalu banyak kelas kecil jauh lebih buruk daripada beberapa kelas besar sebagian besar waktu.
Ryathal
4
Aturan praktis saya adalah: jika Anda tidak dapat melihat implementasi metode secara keseluruhan di layar sekaligus, refactor.
Dan Ray
6
@DanRay, ya, saya dulu punya aturan yang sama, sampai saya membaca Clean Code . Itu cukup mengejutkan, tetapi secara bertahap menyebabkan optimal saya turun menjadi sekitar 10 baris.
Péter Török
2
IMO Clean Code mengerikan dalam hal ekstremitas terhadap metode-metode kecil. Masalahnya adalah ketika metode dibuat lebih kecil, akan ada lebih banyak dari mereka. Tentu saja metode yang terlalu panjang terlalu panjang, tetapi Bob Martin tampaknya lebih memilih 10 metode 1-line daripada 1 10-line satu (dengan demikian kode yang sama secara efektif memakan ruang layar sekitar 5x lebih banyak). Mungkin itu dimaksudkan sebagai semacam trik pendidikan, saya tidak percaya seseorang benar-benar berpikir kode dalam buku itu bagus.
Joonas Pulakka
5
@JoonasPulakka - Katakan saja saya belum pernah membaca metode dan berpikir, "Saya berharap metode ini melakukan lebih banyak." Dengan memperpendek metode, Anda dapat menulis nama metode yang sangat deskriptif yang seringkali dapat menghilangkan kebutuhan untuk membaca keseluruhan metode. Saya menemukan saran dalam Kode Bersih sangat masuk akal. Kita hanya harus setuju untuk tidak setuju. :)
David Harkness
9

Masalah yang lebih penting untuk ditekankan di sini adalah menciptakan abstraksi yang baik . Kelas kecil yang digabungkan secara longgar dan memiliki kohesi yang tinggi adalah produk dari abstraksi yang baik .

Kadang-kadang masuk akal untuk merangkum dua bilangan bulat di kelas. Terutama jika Anda ingin memiliki metode 'terlampir' ke kelas ini untuk juga merangkum bagaimana seseorang dapat memanipulasi atribut ini dan untuk memastikan Anda melindungi mereka dari bagian lain dari program mengubahnya.

Lain positif untuk membuat kelas dalam hal ini adalah bahwa kelas dapat berkembang jauh lebih baik / lebih bagus daripada katakanlah struktur data tingkat yang lebih rendah seperti Peta atau Daftar bisa.

Ketiga, abstraksi yang baik dapat meningkatkan keterbacaan banyak. Kelas yang mematuhi SRP biasanya jauh lebih mudah dipahami oleh manusia daripada kelas yang tidak.

Dan sebagai catatan terakhir ... tidak peduli seberapa bagus seorang siswa Anda ... untuk memahami OOP dan abstraksi yang baik dan kapan menggunakannya, Anda perlu pengalaman. Anda perlu menulis kode yang buruk dan melewati rasa sakit untuk mempertahankannya. Anda perlu melihat orang lain menulis kode yang baik untuk membangun pengetahuan Anda tentang apa yang 'baik' dan apa yang akan menjadi masalah di telepon ... Jadi, jangan menyalahkan diri sendiri jika Anda tidak segera mendapatkannya.

c_maker
sumber
2

Anti-Pola Objek Allah adalah apa yang mungkin disinggung olehnya. Saya cenderung berpikir bahwa jika saya memiliki "dan" dalam deskripsi kelas saya, saya harus memiliki dua kelas. Jika saya memiliki lebih dari sepuluh baris kode dalam suatu metode / fungsi, maka saya harus memecahnya. Sebagai kode bajak laut, itu lebih banyak pedoman daripada aturan.

Sardathrion - Pasang kembali Monica
sumber
2

Dalam pemrograman berorientasi objek, prinsip tanggung jawab tunggal menyatakan bahwa setiap objek harus memiliki tanggung jawab tunggal, dan bahwa tanggung jawab harus seluruhnya dienkapsulasi oleh kelas. Biasanya Anda melakukan lebih dari satu hal jika kelas Anda terlalu besar. Dalam kasus Anda, kelas hanyalah kelas data yang menyimpan data yang benar-benar ok. Anda seharusnya tidak memberi nama kelas PairOfInteger. Apa yang digambarkan bilangan bulat? Tergantung pada skenario Anda, Tuple (seperti dalam C #) mungkin cukup, juga. Dan Anda mungkin ingin berpikir tentang penyangga bukan kelas.

Cobalah untuk membuat Anda kelas kecil. Dan metode lebih kecil. Mungkin 10 Baris?!? Saat ini saya sedang mencoba menggunakan aliran desain dan komponen berbasis acara yang tampaknya membantu menahan kelas kecil. Pertama saya khawatir untuk pergi ke banyak kelas tetapi itu benar-benar berhasil !!! http://geekswithblogs.net/theArchitectsNapkin/archive/2011/03/19/flow-design-cheat-sheet-ndash-part-i-notation.aspx http://geekswithblogs.net/theArchitectsNapkin/archive/2011/03 /20/flow-design-cheat-sheet-ndash-part-i-translation.aspx

KCT
sumber
2

Jadikan sesederhana mungkin, tetapi tidak sederhana. Itulah aturan yang saya coba tempati. Kadang-kadang, sebenarnya masuk akal bagi kelas untuk melakukan apa yang secara tegas berarti lebih dari satu hal, jika hal-hal itu terkait dengan beberapa tema umum . Lihatlah .NET; ada banyak kelas yang mengimplementasikan sejumlah besar antarmuka, masing-masing dengan daftar anggota yang diperlukan. Suatu metode mungkin perlu menjadi agak lama jika melakukan sesuatu yang kompleks dengan sejumlah langkah perantara yang semuanya saling berhubungan dan dengan demikian tidak cocok untuk refactoring lebih lanjut. (Refactoring untuk menjaga metode pendek pada akhirnya harus tentang keterbacaan dan pemeliharaan; jika metode yang panjang lebih mudah dibaca dan / atau dipelihara daripada yang pendek, semuanya sama, saya akan mengambil yang lama setiap hari.)

Untuk hanya "membuat kelas dan metode sekecil mungkin", menurut pendapat saya, salah arah. Tantangan sebenarnya adalah, seperti yang ditunjukkan oleh @c_maker, untuk memberikan abstraksi yang baik. Contoh pengelompokan dua angka Anda bersama sangat bagus, misalnya, jika Anda bekerja pada implementasi aritmatika angka kompleks, atau jika pada sistem Unix Anda perlu merujuk ke konteks pengguna / grup. Sangat tidak masuk akal jika angka-angka tersebut mewakili, katakanlah, ID faktur dan ID produk yang akan ditambahkan ke faktur itu.

sebuah CVn
sumber
0

Itu saran yang oke, tetapi perlu diimplementasikan dengan agak cerdas. Pasti tidak mengikutinya secara membabi buta.

Ketika saya melihat kode saya, saya tahu jika suatu metode terlalu besar. Jika terlalu banyak, dan akan terlalu sulit dibaca, maka itu adalah waktu refactor.

Berikut ini contoh yang bagus: Anda memiliki satu loop, dan Anda mungkin memiliki 60 baris kode dalam metode itu. Dalam hal ini, mungkin saatnya untuk refactor karena Anda cenderung melakukan terlalu banyak dalam metode itu.

Tapi, itu bukan aturan yang keras dan cepat. Itu hanya sesuatu yang bisa Anda pelajari dengan melakukan. Dan, pengembang lain yang bekerja dengan saya tidak selalu setuju dan mungkin memanggil Anda keluar dalam tinjauan kode atau apa pun.

Alan Delimon
sumber
Jangan pernah membuat metode yang lebih kecil daripada mengikuti SRP dan itu akan secara otomatis melakukan pekerjaan.
Vinay Prajapati
0

Paman Bob mengatakan Anda harus refactor / split / ekstrak metode Anda sampai tidak mungkin untuk membuatnya lebih kecil . Ini biasanya berakhir dengan memiliki beberapa metode dengan 3 atau 4 baris masing-masing. Ketika Anda mendapatkan terlalu banyak metode, Anda harus membuat lebih banyak kelas.

Jika Anda mencoba mengikuti SRP dan satu level abstraksi per metode, aturan-aturan ini sangat membantu Anda. Setidaknya mereka melayani saya dengan baik. Bertujuan untuk "sekecil mungkin" memberi saya metode kecil yang masuk akal, karena biasanya saya gagal mencapai tujuannya.

Dan selalu lebih mudah untuk memahami kelas yang lebih kecil. Silakan, baca "Kode Bersih"

Peter Kofler
sumber