Bagaimana memiliki terlalu banyak variabel instan yang menyebabkan kode duplikat?


19

Menurut Refactoring ke Pola :

Ketika sebuah kelas mencoba melakukan terlalu banyak, ia sering muncul sebagai terlalu banyak variabel instan. Ketika sebuah kelas memiliki terlalu banyak variabel instan, kode duplikat tidak bisa jauh di belakang.

Bagaimana memiliki terlalu banyak variabel instan yang menyebabkan kode duplikat?


2
Sederhananya: nvariabel boolean misalnya membuat ruang keadaan internal 2^n. Lebih sering daripada tidak meskipun objek Anda tidak memiliki banyak status yang dapat diamati , tetapi karena Anda menjejalkan semua keadaan itu menjadi satu objek, secara internal Anda masih harus menangani semuanya.
biziclop

Jawaban:


23

Memiliki terlalu banyak variabel instan tidak secara langsung terkait dengan kode duplikat, atau sebaliknya. Pernyataan ini, secara umum ini, salah. Satu dapat membuang dua kelas terpisah tanpa kode duplikat ke dalam satu kelas - yang menghasilkan kelas baru dengan tanggung jawab yang tidak terpisahkan dan terlalu banyak variabel contoh, tetapi masih tidak ada kode duplikat.

Tetapi ketika Anda menemukan kelas dengan terlalu banyak tanggung jawab dalam kode warisan dunia nyata, kemungkinan besar programmer yang menulisnya tidak peduli dengan kode bersih atau prinsip SOLID (setidaknya, tidak pada saat ia menulis kode itu), jadi itu bukan tidak mungkin Anda akan menemukan kode lain berbau seperti kode duplikat di sana.

Sebagai contoh, anti-pola "copy-paste reuse" sering diterapkan dengan menyalin metode lama dan membuat sedikit modifikasi untuk itu, tanpa refactoring yang tepat. Kadang-kadang, untuk membuat ini berfungsi, kita harus menduplikasi variabel anggota dan sedikit memodifikasi variabel itu. Ini mungkin menghasilkan kelas dengan terlalu banyak variabel instan (lebih tepat: terlalu banyak variabel instan yang mirip). Dalam situasi seperti itu, variabel instance yang sama mungkin merupakan indikator untuk kode berulang di tempat lain di kelas. Namun, seperti yang Anda perhatikan, ini adalah contoh buatan, dan saya tidak akan menyimpulkan aturan umum darinya.


11

Terlalu banyak variabel instan berarti terlalu banyak keadaan. Status terlalu banyak mengarah ke kode duplikat yang hanya sedikit berbeda untuk masing-masing negara.

Ini adalah kelas beton tunggal klasik yang melakukan terlalu banyak hal yang seharusnya menjadi sub-kelas atau komposisi.

Temukan beberapa kelas yang memiliki terlalu banyak variabel instan, Anda akan melihat mereka mempertahankan status terlalu banyak dan memiliki banyak jalur kode duplikat yang hanya sedikit terspesialisasi untuk setiap kasus, tetapi berbelit-belit sehingga mereka tidak dapat dipecah menjadi metode yang dapat digunakan kembali. Ini adalah salah satu sumber terbesar side effectsjuga.

Setidaknya ada satu pengecualian untuk hal ini yang tidak termasuk dalam kategori ini dan merupakan cara mudah untuk memulihkannya. Immutableobjek tidak memiliki masalah ini, karena mereka adalah keadaan tetap, tidak ada peluang untuk manajemen negara yang berbelit-belit atau efek samping.


7

Pernyataan yang Anda kutip dimaksudkan untuk dilihat dalam konteks tertentu.

Menurut pengalaman saya, saya tidak dapat mengkonfirmasi bahwa "banyak variabel instance secara umum menunjukkan kode duplikat". Juga, perhatikan bahwa ini milik "kode bau", dan ada bau yang diduga bertentangan. Lihat di sini:

http://c2.com/cgi/wiki?CodeSmell

Yang mengherankan, Anda akan menemukan "terlalu banyak variabel instan" sama bagusnya dengan bau kode "terlalu sedikit variabel instan".

Tetapi ada masalah dengan variabel instan, baik terlalu sedikit atau terlalu banyak:

  1. Setiap variabel instan dapat berarti semacam status objek. Stati selalu membutuhkan perawatan yang cermat. Anda harus memastikan bahwa Anda telah membahas semua kemungkinan kombinasi stati untuk menghindari perilaku yang tidak terduga. Anda harus selalu jelas sekarang: status apa yang dimiliki objek saya saat ini? Dari sudut ini, banyak variabel instan dapat mengindikasikan bahwa kelas telah menjadi tidak dapat dipertahankan. Ini juga dapat menunjukkan bahwa suatu kelas melakukan terlalu banyak pekerjaan, karena itu membutuhkan banyak stati.

  2. Setiap variabel instan mengharuskan Anda untuk tetap mengawasi, metode mana yang mengubah variabel dengan cara apa. Jadi, tiba-tiba, Anda tidak tahu lagi semua koki yang memasak. Salah satunya, diprogram dengan lelah di larut malam, akan merusak sup Anda. Sekali lagi: terlalu banyak variabel seperti itu akan menyebabkan kode sulit ditembus.

  3. Sisi lain: terlalu sedikit variabel instance dapat menyebabkan banyak metode harus menangani informasinya dengan terlalu banyak pekerjaan dan dengan terlalu banyak parameter. Anda merasakan hal ini, jika Anda memberikan kepada beberapa metode Anda parameter yang sama, dan semua metode melakukan hal yang sangat mirip dengan parameter ini. Dalam situasi itu, kode Anda akan mulai membengkak. Anda akhirnya akan menggulir banyak layar ke atas dan ke bawah untuk mendapatkan beberapa hal sederhana bersama. Di sini, sebuah refactoring dapat membantu: memperkenalkan satu variabel instan dan satu pintu masuk yang jelas untuknya. Lalu, bebaskan semua metode.

  4. Last but not least: Jika banyak variabel instan dari kelas memiliki masing-masing setter dan pengambil, maka itu mungkin menunjukkan bahwa kelas lain tidak menggunakan kelas pertama ini dengan cara yang benar. Ada diskusi tentang " Mengapa getter dan setter itu jahat ". Ide singkatnya adalah, jika suatu kelas Rectanglemenawarkan beberapa getX(), dan lusinan kelas lain digunakan rectangle.getX(), maka Anda menulis kode yang tidak kuat terhadap "efek riak" (seberapa jauh perubahan kode mempengaruhi kode lain). Cukup tanyakan apa yang terjadi jika Anda mengubah jenis dari intke double? Menurut diskusi ini, banyak dari rectangle.getX()panggilan seharusnya sebenarnya panggilan sepertirectanlge.calculateThisThingForMe(). Jadi, sangat tidak langsung, kode duplikat dapat muncul dari banyak variabel instan, karena banyak kelas di sekitar menggunakan banyak getter dan setter melakukan hal-hal yang sangat mirip, yaitu hal-hal yang disalin, yang sebaiknya dipindahkan di dalam kelas.

Banyak atau beberapa variabel instan tetap merupakan trade off permanen, mengubah kedua arah ketika perangkat lunak tumbuh.


Kutipan R-to-P terlalu umum sehingga saya menyukai jawaban ini. Pilihan saya adalah: jika kami mengekspos properti yang cukup, klien dapat, dan akan, mengambilnya dan menulis versi sendiri dari fungsionalitas yang diberikan - # 4 di atas. Masalahnya bisa sedalam komposisi objek - lihat # 2: Saya melihat ini terlalu sering dalam kode kita. (a) "mengapa mereka tidak menggunakan kelas <whthing> (untuk mengurung beberapa negara yang tidak terorganisir ini)?" atau (b) "Mengapa mereka tidak membuat kelas baru? Saya tidak bisa melacak semuanya." Dan tentu saja kami memiliki beberapa kelas fungsi duplikasi internal karena kurangnya kelas yang koheren.
radarbob

6

Sederhananya: pemisahan yang buruk dari masalah dalam kode, mengarah ke kode yang tidak modular, mengarah ke penggunaan kembali yang buruk, mengarah ke kode digandakan.

Jika Anda tidak pernah mencoba mengulangi fungsionalitas, Anda tidak akan mendapatkan kode duplikat, dan banyak variabel instan, tidak akan menjadi masalah.

Jika Anda mencoba mengulangi fungsionalitas, maka kode monolitik, yang bukan modular, tidak dapat digunakan kembali. Itu terlalu banyak dan hanya bisa melakukan apa yang dilakukannya. Untuk melakukan sesuatu yang serupa, tetapi tidak sama, itu "lebih mudah" untuk memotong dan menempel, daripada memecah kode monolitik. Pemrogram pengalaman tahu bahwa kode duplikat adalah jalan menuju neraka.

Jadi, sementara banyak variabel instan itu sendiri bukan akar penyebab masalah, itu adalah "bau" yang kuat bahwa masalahnya akan datang.

Bahasa "tidak mungkin jauh di belakang" lebih lemah daripada mengatakan "pasti harus mengikuti" sehingga penulis tidak mengklaim itu harus terjadi tetapi pada akhirnya akan terjadi; jika Anda perlu menggunakan kembali fungsi tetapi tidak bisa karena kode tidak modular.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.