Kapan menulis kode abstrak dan kapan harus lebih spesifik?

9

Saya sedang mengerjakan alat kecil sebagai proyek mainan untuk menunjukkan perbedaan antara dua direktori, menunjukkan file / direktori mana yang ditambahkan, dihapus, dimodifikasi, dll.

Saya mencoba mewakili perubahan ini hanya sebagai objek 'ChangeItem', tanpa membedakan apakah itu file atau direktori. Namun, itu menciptakan banyak masalah, misalnya bagaimana menampilkannya di pohon, cara mengetahui siapa orang tua seorang anak, dll. Dan itu juga sangat tidak intuitif.

Saya kemudian membagi perubahan antara perubahan direktori dan perubahan file. Itu segera membuatnya sangat mudah untuk kode dan untuk memahami apa yang sedang terjadi. Sekarang lebih mudah untuk memilih semua file dalam direktori, dll.

Pertanyaan saya adalah, bagaimana orang bisa tahu apakah akan menggunakan abstraksi atau untuk lebih spesifik dalam kode mereka? Bagaimana Anda bisa tahu jika Anda memiliki terlalu banyak atau terlalu sedikit abstraksi?

Klik Upvote
sumber

Jawaban:

9

Bagaimana seorang pelukis tahu apakah terlalu banyak atau terlalu sedikit ungu?

Dia mencampur warna, mencoba pukulan, membuat beberapa sketsa dan melihat apa yang terjadi. Kemudian ia menyesuaikan proporsi sampai seluruh gambar terlihat bagus dan memancarkan harmoni.

Kami melakukan hal yang sama dengan kode. Kami mendapatkan ide implementasi pertama kali, merenungkannya, menganalisis sisi kuat dan minggu lalu mencoba untuk melihat apakah itu berhasil. Kemudian kita menyelaraskan ide dalam proses berulang untuk menyesuaikan proporsi abstrak, enkapsulasi, polimorfisme, dan apa pun hingga terlihat benar dan berfungsi sesuai kebutuhan.


sumber
21

Anda menulis kode konkret terlebih dahulu.

Anda menulis kode abstrak saat Anda harus karena itu menyederhanakan kode konkret.

Paling mudah untuk memulai dengan beton dan menemukan abstraksi setelah mempelajari apa yang mirip dan berbeda tentang beton.

S.Lott
sumber
13
Ingatlah selalu Aturan Tiga: abstraksi tanpa setidaknya tiga klien bukanlah abstraksi. Itu adalah angan-angan. Biasanya salah. Abstraksi yang baik diekstraksi , tidak dirancang.
Jörg W Mittag
3

Anda menulis kode abstrak saat Anda menulis pustaka, dan harus menggeneralisasi fungsionalitasnya sehingga akan berfungsi dalam berbagai kondisi.

Tetapi menulis perpustakaan dengan cara ini sulit. Dalam aplikasi normal (katakanlah, lini aplikasi bisnis), generalisasi semacam ini dianggap sebagai bentuk "optimisasi prematur," umumnya ditandai sebagai "Anda tidak akan membutuhkannya" (YAGNI).

Ada titik kritis di mana kode berulang menuntut solusi yang lebih umum dirancang. Tetapi biasanya jenis refactoring untuk menghilangkan redundansi ini jauh lebih sederhana daripada menulis perpustakaan umum.

Pada akhirnya, kompleksitas tambahan yang diperlukan untuk mengimplementasikan solusi abstrak harus dibenarkan oleh fleksibilitas yang mereka tawarkan.

Robert Harvey
sumber
3

Aturan praktis yang saya ikuti, yang cukup umum, adalah Anda tidak boleh mencoba untuk mengabstraksikan sesuatu sampai Anda menemukan diri Anda menulisnya untuk ketiga kalinya.

Pertama kali Anda benar-benar tidak memahami domain masalah dan akhirnya akan merancang-ulang semua bagian yang salah. Kedua kalinya Anda diposisikan dengan sempurna untuk membangun solusi ideal untuk masalah terakhir Anda. Ketiga kalinya Anda akhirnya dalam posisi yang baik untuk membuat abstraksi yang tepat yang akan membantu Anda dalam hal-hal yang perlu diubah, dan tidak menghalangi Anda untuk menyelesaikan hal-hal sederhana.

btilly
sumber
1
Waktu ketiga adalah aturan praktis yang baik. Saya merasa jarang menggeneralisasi jauh sebelum waktu ke-3 menulis sesuatu.
quentin-starin
1
Bukankah itu juga tergantung pada seberapa besar kode yang sama? Anda tidak akan menyalin dan menempel dua halaman kode yang hanya berbeda oleh dua baris, hanya karena Anda belum mencapai "3 kali" ajaib.
Scott Whitlock
@ scott-whitlock: Jelas. Itu sebabnya itu adalah aturan praktis. Abaikan itu sesuai kebutuhan. Selain itu ada perbedaan antara abstraksi organik (misalnya, "Saya membutuhkan bilah hampir persis foo, jadi saya hanya menambahkan parameter opsional ke foo") dan abstraksi yang merupakan bagian dari desain depan Anda.
btilly
1
@Scott Whitlock: "Anda tidak akan menyalin dan menempel dua halaman kode yang hanya berbeda oleh dua baris". Itu bukan panggilan untuk abstraksi. Itu masih desain yang bagus. Aturan 3x harus dijaga dengan sangat, sangat ketat untuk menghindari desain abstrak prematur.
S.Lott
"Yang sesuai" adalah frasa kunci di sini. Dua sen saya - sering "berlaku komposisi untuk warisan" berlaku. Kadang-kadang masalah yang diselesaikan dengan abstraksi akan lebih baik if (cond) { //use one object} else {// use the other object }, khususnya. ketika itu adalah set keputusan biner.
Michael K
2

Dengan membaca pertanyaan saya akan mengatakan bahwa Anda bisa abstrak dan spesifik. Apakah hanya masalah konteks, gunakan representasi paling abstrak yang mungkin dalam setiap konteks.

Untuk aplikasi mainan spesifik Anda, ChangeItemadalah representasi perubahan yang paling abstrak. Kemudian Anda menjadi lebih spesifik dengan DirectoryChangeItemdan FileChangeItem, melalui warisan. Anda dapat menggunakan pola komposit untuk memodelkan pohon. Saat Anda ingin menampilkannya, Anda bisa menggunakan representasi spesifik dan ketika men-traversenya Anda bisa menggunakan representasi abstrak.

Dan untuk memberikan jawaban konkret untuk pertanyaan: sespesifik mungkin sampai Anda merasa bahwa Anda membutuhkan lapisan lain di bawahnya.

Victor Hurdugaci
sumber
1

Biasanya abstraksi berguna untuk memerangi hal-hal seperti Complexity, Entropy, untuk membuat kode Anda menjadi Cybernetic, dan bahkan pada tingkat keterbacaan yang rendah. Saya akan hardcode pertama - HANYA jika abstraksi tidak jelas di muka. Sebagian besar abstraksi terjadi ketika lebih dari satu implementasi memiliki pola yang sama.

Pikirkan abstraksi sebagai kongruensi atau kesatuan dari 2 set atau lebih. Ambil Diagram Venn sebagai model sederhana: Bagian di mana lingkaran tumpang tindih, atau dengan kata lain, Set menggabungkan.

Jika saya memiliki dua set: A: {a, b, c, d, e} dan B: {d, e, f, g, h}. Titik di mana saya akan mulai mencari abstrak adalah kesatuan A + B; {d, e} adalah tempat abstrak. Demikian pula, jika mereka yang berada dalam perbedaan A & B (AB atau BA) saling isomorfik, artinya biayanya yang rendah untuk membuat a, b atau c dari f, g atau h (dan sebaliknya), maka saya akan tetap abstraksi di belakang pikiran saya.

Cody
sumber