Contoh
Saya menemukan kode monolitik yang melakukan "segalanya" di satu tempat - memuat data dari basis data, menunjukkan markup HTML, bertindak sebagai router / controller / action. Saya mulai menerapkan kode database bergerak SRP ke file sendiri, memberikan penamaan yang lebih baik untuk hal-hal, dan semuanya terlihat bagus, tapi kemudian saya mulai ragu mengapa saya melakukan ini.
Mengapa refactor? Apa tujuannya? Apakah itu tidak berguna? Apa manfaatnya? Perhatikan bahwa saya kebanyakan meninggalkan file monolitik seperti apa adanya, tetapi hanya me-refacted bagian yang lebih kecil yang relevan dengan area di mana saya perlu melakukan beberapa pekerjaan.
Kode asli:
Untuk memberikan contoh nyata, saya menemukan potongan kode ini - ia memuat spesifikasi produk baik oleh id produk yang dikenal, atau oleh id versi yang dipilih pengguna:
if ($verid)
$sql1 = "SELECT * FROM product_spec WHERE id = " . clean_input($verid);
else
$sql1 = "SELECT * FROM product_spec WHERE product_id = " . clean_input($productid) ;
$result1 = query($sql1);
$row1 = fetch_array($result1);
/* html markup follows */
Refactoring:
Karena saya sedang melakukan pekerjaan yang mengharuskan saya untuk mengubah hal-hal di bagian kode ini, saya mengubahnya untuk menggunakan pola repositori dan memutakhirkannya untuk menggunakan fasilitas MySQL berorientasi objek:
//some implementation details omitted
$this->repository = new SpecRepository($mysql);
if ($verid)
$row1 = $this->repository->getSpecByVersion($verid);
else
$row1 = $this->repository->getSpecByProductId($productid);
/* html markup follows to be refactored or left alone till another time*/
//added new class:
class SpecRepository extends MySqlRepository
{
function getSpecByVersion(int $verid)
{
return $this->getMySql()->paramQuery("
SELECT * FROM product_spec WHERE id = ?
", $verid)->getSingleArray();
}
function getSpecByProductId(int $productid)
{
return $this->getMySql()->paramQuery("
SELECT * FROM product_spec WHERE product_id = ?
", $productid)->getSingleArray();
}
}
Haruskah saya melakukan ini?
Melihat kembali perubahan, kodenya masih ada, kode dengan fungsi yang sama, tetapi dalam file yang berbeda, nama yang berbeda, tempat, menggunakan gaya berorientasi objek yang lebih daripada prosedural. Sebenarnya itu lucu untuk dicatat bahwa kode refactored terlihat jauh lebih besar meskipun memiliki fungsi yang sama.
Saya memperkirakan beberapa jawaban mengatakan "jika Anda tidak tahu alasan mengapa Anda menolak, jangan lakukan itu", dan mungkin saya mungkin setuju. Alasan saya adalah untuk meningkatkan kualitas kode dari waktu ke waktu (dan harapan saya adalah bahwa saya akan melakukannya dengan mengikuti SRP dan prinsip-prinsip lain).
Apakah itu alasan yang cukup baik atau saya membuang-buang waktu saya pada "menata ulang kode sekitar" dengan cara ini? Secara keseluruhan, refactoring ini terasa seperti menginjak air dengan jujur - ini membutuhkan waktu dan menjadi lebih "terpisah" sejauh SRP berjalan tetapi meskipun ada niat baik saya, saya tidak merasa seperti saya melakukan perbaikan yang luar biasa. Karenanya, berdebat apakah yang terbaik untuk meninggalkan kode seperti sebelumnya dan bukan refactor.
Mengapa saya refactor sejak awal?
Dalam kasus saya, saya menambahkan fungsionalitas baru untuk lini produk baru, jadi saya harus mengikuti struktur kode yang ada untuk lini produk serupa, atau menulis sendiri.
Select * from ..
dapat dianggap sebagai anti-pola. Lihat stackoverflow.com/q/3639861/31326select *
menjadi "praktik terbaik."Jawaban:
Dalam contoh konkret yang Anda berikan, refactoring mungkin tidak diperlukan, setidaknya belum. Tetapi Anda melihat bahwa ada potensi kode berantakan di masa depan yang akan mengarah pada refactoring yang lebih lama dan lebih membosankan, jadi Anda mengambil inisiatif dan membersihkan semuanya sekarang.
Saya juga akan mengatakan keuntungan yang Anda peroleh di sini adalah kode yang lebih mudah dipahami, setidaknya dari sudut pandang saya, sebagai seseorang yang tidak tahu basis kode Anda.
Secara umum:
Apakah refactoring memudahkan pengembang lain untuk memahami kode Anda?
Apakah refactoring membuatnya lebih mudah untuk meningkatkan kode?
Apakah refactoring membuatnya lebih mudah untuk mempertahankan kode?
Apakah refactoring membuatnya lebih mudah untuk di-debug?
Jika jawaban untuk semua ini adalah "ya", maka itu layak, dan itu lebih dari sekadar "memindahkan kode?"
Jika jawaban untuk semua ini adalah "tidak", maka mungkin itu tidak perlu di refactored.
Ukuran akhir basis kode mungkin lebih besar dalam hal LoC (meskipun beberapa refactoring dapat mengecilkan basis kode dengan merampingkan kode berlebihan), tetapi itu seharusnya tidak menjadi faktor jika ada keuntungan lain.
sumber
Refactoring benar-benar kembung jika Anda membongkar sebuah monolith.
Namun, Anda sudah menemukan manfaatnya.
"Dalam kasus saya, saya menambahkan fungsionalitas baru untuk lini produk baru."
Anda tidak dapat menambahkan fungsionalitas ke monolith dengan mudah tanpa merusaknya.
Anda mengatakan bahwa kode yang sama mendapatkan data dan melakukan markup. Hebat, sampai Anda ingin mengubah kolom mana yang Anda pilih dan manipulasi untuk ditampilkan dalam kondisi tertentu. Tiba-tiba, kode markup Anda berhenti bekerja dalam kasus tertentu dan Anda harus melakukan refactor.
sumber
if/else
blok baru dan mengikuti gaya kode asli untuk menambahkan pernyataan SQL, dan kemudian saya akan menempatkan markup HTML baru di file monolith yang sama. Dan untuk mengubah kolom saya akan menemukan if / else block yang bertanggung jawab untuk menampung baris SQL, dan mengedit SQL itu untuk membuat perubahan pada kolom, tanpa memecah file itu.Saya mempertimbangkan refactoring jika saya tahu bahwa saya harus bekerja berbulan-bulan atau bahkan bertahun-tahun dengan proyek itu. Jika saya harus melakukan perubahan di sana-sini, maka saya menahan diri saya untuk memindahkan kode.
Cara yang disukai untuk melakukan refactoring adalah ketika saya memiliki kode dasar dengan semacam tes otomatis. Meski begitu saya harus sangat berhati-hati dengan apa yang saya ubah untuk memastikan semuanya berjalan seperti sebelumnya. Anda akan kehilangan kepercayaan segera jika Anda memberikan bug di area lain dari yang seharusnya Anda kerjakan.
Saya menghargai refactoring karena alasan berikut:
comment
kode melalui nama variabel, nama metodearchitect
solusinya. Ini akan datang saat menulis - menulis ulang kode bolak-balik.Dalam dunia yang sempurna, refactoring harus diverifikasi oleh unit test, tes integrasi seterusnya. Jika tidak ada, coba tambahkan. Juga beberapa IDE mungkin banyak membantu. Saya biasanya menggunakan plugin yang membutuhkan biaya. Saya ingin menghabiskan sedikit waktu dengan refactorings dan menjadi sangat efisien.
Saya juga memperkenalkan bug. Saya dapat melihat mengapa beberapa QA bertanya.
are you guys doing refactoring? because everything stopped working!
Ini adalah risiko yang harus dihadapi tim dan kami harus selalu transparan tentang hal itu.Selama bertahun-tahun saya menemukan bahwa refactoring berkelanjutan meningkatkan produktivitas saya. Jauh lebih mudah untuk menambahkan fitur baru. Rekondisi besar juga tidak memerlukan penulisan ulang keseluruhan seperti yang sering terjadi ketika basis kode tidak disesuaikan dengan evolusi produk. Itu juga menyenangkan.
sumber
I
denganto
.Saya pikir pertanyaan yang harus Anda tanyakan pada diri sendiri adalah tidak begitu banyak "Apakah ada manfaatnya?" tetapi "Siapa yang akan membayar pekerjaan ini?"
Kita semua dapat berdebat tentang manfaat yang dirasakan sampai akhir hari, tetapi kecuali jika Anda memiliki pelanggan yang percaya pada manfaat itu dan menilai mereka cukup untuk membayar perubahan Anda tidak harus melakukannya.
Ini semua terlalu mudah ketika Anda berada di tim pengembang di suatu tempat untuk melihat kode dan ingin mengubahnya menjadi 'lebih baik'. Tetapi memberikan nilai pada 'kode yang lebih baik' ketika produk sudah bekerja sangat sulit.
Hal-hal seperti 'pengembangan fitur baru yang lebih cepat' tidak memotongnya karena hanya mengurangi biaya. Anda perlu menghasilkan penjualan.
sumber
Menurut saya refactoring adalah investasi yang bagus.
Kalau tidak, Anda akan segera mendapatkan utang teknis (masalah yang tidak terpecahkan, kode buruk yang hanya berfungsi dalam kondisi tertentu, dll.). Utang teknis akan segera menjadi lebih besar dan lebih besar, sampai perangkat lunak tidak lagi dapat dipertahankan.
Tetapi untuk membuat refactoring berfungsi, Anda juga harus berinvestasi dalam tes. Anda harus membuat tes otomatis, idealnya Anda harus memiliki tes unit dan tes integrasi. Ini memudahkan Anda dari melanggar kode yang ada.
Jika Anda harus meyakinkan bos atau kolega Anda, Anda harus membaca beberapa buku tentang metode gesit (misalnya SCRUM) dan pengembangan yang didorong oleh tes.
sumber