Mungkin janji terbesar menggunakan paradigma berorientasi objek adalah penggunaan kembali kode. Beberapa membantah bahwa ini tercapai. Mengapa itu (tidak) tercapai?
Apakah kode digunakan kembali ketika OOP mendefinisikannya, membuat proyek lebih produktif?
Atau lebih mudah dikelola? Atau lebih mudah dirawat? Atau dengan kualitas lebih?
Mungkin kita semua sepakat bahwa penggunaan kembali kode adalah hal yang baik, tetapi ada beberapa cara untuk mencapai tujuan ini. Pertanyaannya adalah tentang metode penggunaan kembali kode yang ditawarkan oleh OOP. Apakah itu hal yang baik? Adakah metode yang lebih baik untuk mencapai penggunaan kembali kode daripada orientasi objek, sub-klasifikasi, polimorfisme, dll.? Cara apa yang lebih baik? Mengapa ?
Ceritakan pengalaman Anda dengan OOP reuse atau paradigma lain reuse.
Jawaban:
Penggunaan kembali kode adalah ide yang cukup bagus. Bukan yang hebat .
Saya memiliki perspektif yang diambil dari sekitar 30 tahun rekayasa perangkat lunak, mencoba "menggunakan kembali".
Saya mulai menyelidiki "penggunaan kembali kode" sebagai topik penelitian di tahun 80-an, setelah menemukan saya telah menggunakan kembali desain satu OS yang saya bangun pada awal 70-an, untuk OS lain yang saya bangun pada akhir 70-an.
Bagian yang baik dari penggunaan kembali kode adalah kemampuan untuk terkadang menggunakan kembali kode yang sudah ada sebelumnya yang jujur. Tetapi dunia ini penuh dengan kode; bagaimana bisa menemukan yang Anda inginkan? Inilah yang saya sebut Kutukan Penggunaan Kembali :
Saya Santa Claus (ok Open Source), dan saya memiliki 1 miliar komponen perangkat lunak. Anda dapat memiliki salah satu dari mereka.
Semoga beruntung memilih.
Untuk memecahkan masalah penggunaan kembali dengan baik:
Sebagian besar yang telah ditemukan selama bertahun-tahun adalah bahwa agar kode dapat digunakan kembali, itu semacam harus dirancang untuk tujuan itu, atau mengandung terlalu banyak asumsi implisit. Pustaka penggunaan kembali kode yang paling sukses sebenarnya cukup kecil. Pustaka dan kerangka kerja bisa jadi adalah kode yang "dapat digunakan kembali" dan sangat sukses; Java dan C # berhasil bukan karena mereka adalah bahasa komputer yang cukup bagus, tetapi karena mereka memiliki perpustakaan yang dirancang dengan baik, diimplementasikan dan didokumentasikan. Tetapi orang-orang tidak melihat kode sumber di perpustakaan; mereka hanya memanggil API yang terdokumentasi dengan baik (dirancang agar dapat digunakan secara umum).
Apa yang tidak digunakan kembali oleh kode (OOP) tidak memberikan perintah peningkatan besar dalam kemampuan kami untuk kode sistem.
Saya pikir kuncinya adalah bahwa segala jenis penggunaan kembali kode pada dasarnya terbatas karena kode memiliki terlalu banyak asumsi . Jika Anda membuat kode kecil, Anda meminimalkan asumsi, tetapi kemudian biaya untuk membangun dari awal tidak terlalu besar dan keuntungan penggunaan kembali tidak efektif. Jika Anda membuat potongan kode besar, mereka cukup berguna dalam konteks baru. Seperti Gulliver, mereka diikat ke pantai oleh sejuta string kecil, dan Anda tidak bisa memotong semuanya.
Apa yang harus kita kerjakan adalah penggunaan kembali pengetahuan untuk membuat kode . Jika kita dapat melakukan ini, maka kita dapat menerapkan pengetahuan itu untuk membuat kode yang kita butuhkan, menangani sekumpulan asumsi saat ini.
Untuk melakukan ini, kita masih memerlukan kemampuan spesifikasi yang sama untuk mengkarakterisasi komponen perangkat lunak (Anda masih harus mengatakan apa yang Anda inginkan!). Tetapi kemudian Anda menerapkan pengetahuan "konstruksi" ini pada spesifikasi untuk menghasilkan kode yang Anda inginkan.
Sebagai sebuah komunitas, kami belum begitu pandai dalam hal ini. Tetapi orang-orang melakukannya sepanjang waktu; mengapa kita tidak bisa mengotomatiskannya? Ada banyak penelitian, dan ini menunjukkan hal itu dapat dilakukan dalam banyak keadaan.
Salah satu bagian penting dari mesin yang diperlukan untuk ini adalah alat mekanis untuk menerima "deskripsi komponen" (ini hanya dokumen formal dan dapat diuraikan seperti bahasa pemrograman) dan menerapkan transformasi program pada mereka.
Compiler sudah melakukan ini: -} Dan mereka benar-benar bagus di kelas masalah yang mereka tangani.
Model UML dengan pembuatan kode adalah salah satu upaya untuk melakukan ini. Bukan usaha yang sangat bagus; cukup banyak yang dikatakan dalam kebanyakan model UML adalah "Saya punya data yang terlihat seperti ini". Cukup sulit untuk menghasilkan program nyata jika fungsinya ditinggalkan.
Saya mencoba membangun sistem transformasi program praktis, alat yang disebut DMS . Sudah cukup terganggu dengan menerapkan transformasi program tidak begitu banyak untuk spesifikasi abstrak untuk menghasilkan kode, tetapi lebih ke kode lama untuk membersihkannya. (Ini adalah masalah yang sama dalam abstrak!). (Untuk membangun alat seperti itu membutuhkan banyak waktu; Saya sudah melakukan ini selama 15 tahun dan sementara itu Anda harus makan).
Tetapi DMS memiliki dua sifat utama yang saya jelaskan di atas: kemampuan untuk memproses spesifikasi formal yang sewenang-wenang, dan kemampuan untuk menangkap "pengetahuan pembuatan kode" sebagai transformasi, dan menerapkannya sesuai permintaan. Dan yang luar biasa, kami menghasilkan dalam beberapa kasus khusus, beberapa kode yang agak menarik dari spesifikasi; DMS sebagian besar dibangun menggunakan dirinya sendiri untuk menghasilkan implementasinya. Itu telah mencapai bagi kita setidaknya beberapa janji penggunaan kembali (pengetahuan): peningkatan produktivitas yang sangat signifikan. Saya memiliki tim yang terdiri dari sekitar 7 orang teknis; kami telah menulis mungkin 1-2 MSLOC dari "spesifikasi" untuk DMS, tetapi memiliki 10MSLOC kode yang dihasilkan.
Ringkasan: penggunaan kembali pengetahuan generasi adalah kemenangan, bukan penggunaan kembali kode .
sumber
Mostly what has been discovered over the years is that for code to be reusable, it sort of has to be designed for that purpose, or it contains too many implicit assumptions.
Saya telah mencapai kesimpulan yang sama tetapi saya tidak bisa mengungkapkannya dengan ringkas.Penggunaan kembali kode dicapai dalam OOP tetapi juga dicapai dalam pemrograman fungsional. Kapan saja Anda mengambil blok kode dan membuatnya dapat dihubungi oleh seluruh kode Anda sehingga Anda dapat menggunakan fungsi ini di tempat lain adalah penggunaan kembali kode.
Jenis penggunaan kembali kode ini juga membuat kode lebih mudah dikelola karena mengubah blok yang dapat dipanggil ini mengubah semua tempat yang disebutnya. Saya akan mengatakan hasil ini juga meningkatkan kualitas dan keterbacaan.
Saya tidak yakin OOP ada di sana hanya untuk menyediakan kembali kode. Saya melihat OOP sebagai lebih dari cara untuk berinteraksi dengan objek dan abstrak jauh rincian struktur data.
Dari Wikpedia:
sumber
double sqrt (double x)
? Fungsi murni adalah pola dasar penggunaan kembali.double sqrt(double x)
,float sqrt(float x)
,int sqrt(int x)
Anda dapat menentukan banyak dari mereka, sementara dengan bahasa Pemrograman Generik Anda harusNumber sqrt(Number x)
dan dilakukan dengan hal itu.Iya dan tidak
Penggunaan kembali kode adalah istilah umum untuk semua kegiatan yang berbeda.
sumber
Saya akan mengirim jawaban yang panjang tetapi mengapa? Udi Dahan menjelaskannya lebih baik daripada yang saya bisa.
http://www.udidahan.com/2009/06/07/the-fallacy-of-reuse/
Inilah awal tulisan:
sumber
Saya setuju dengan Chris, pemrograman fungsional adalah cara yang baik untuk menggunakan kembali kode.
Banyak program memiliki struktur kode yang berulang. Untuk ini beberapa pola desain digunakan di dunia OOP, tetapi ini dapat dicapai dengan fungsi rekursif dan pencocokan pola dalam bahasa pemrograman fungsional. Untuk lebih lanjut tentang ini, lihat bab pertama dalam Pemrograman Fungsional Dunia Nyata .
Saya pikir warisan dalam OOP bisa menyesatkan dalam banyak kasus. Anda memiliki kelas dan banyak metode terkait erat diimplementasikan dalam file yang berbeda. Seperti yang dikatakan Joe Armstrong tentang OOP:
Fungsi pesanan tinggi juga sangat berguna dalam hal penggunaan kembali kode misalnya
map
danfoldr
itu adalah dasar untuk Google MapReduce .Melewati pesan asinkron juga merupakan cara yang baik untuk mengatur perangkat lunak yang kompleks, dan beberapa ilmuwan komputer menyatakan bahwa objek diasumsikan berkomunikasi dengan satu sama lain secara tidak sinkron seperti pada Tell, jangan tanyakan prinsip OOP. Lihat lebih lanjut tentang ini di Pemrograman Berorientasi Objek: The Wrong Path? adalah Joe Armstrong adalah dikutip:
Melewati pesan yang tidak sinkron seperti pada sistem yang digerakkan oleh peristiwa dan di Erlang juga merupakan cara yang sangat baik untuk memisahkan sistem dan pelepasan longgar adalah penting dalam sistem yang kompleks. Dengan sistem yang cukup terpisah Anda dapat mengembangkan sistem saat sedang berjalan, mungkin pada node yang berbeda. Unibet membuat presentasi yang luar biasa tentang ini: Domain Event Driven Architecture
Namun saya berpikir bahwa sebagian besar penggunaan kembali kode dilakukan dengan menggunakan pustaka dan kerangka kerja.
sumber
Pipa unix sederhana telah melakukan lebih banyak untuk menggunakan kembali kode daripada apa pun yang telah datang dan pergi. Objek baru saja terjadi menjadi cara intuitif menyusun kode ketika mereka datang dan kemudian orang mulai menempel pada apa saja dan segala sesuatu ke dalamnya. Secara umum objek adalah untuk enkapsulasi dan bukan untuk penggunaan kembali kode, penggunaan kembali kode membutuhkan sesuatu yang lebih dan hierarki pewarisan kelas adalah pengganti yang buruk untuk apa seharusnya mekanisme penggunaan kembali kode.
sumber
OOP tidak istimewa; Anda dapat membuat kode yang dapat digunakan kembali dengan atau tanpa OOP. Fungsi murni sangat dapat digunakan kembali : misalnya,
java.lang.math.sqrt(double)
mengambil nomor dan memberikan nomor. Tidak ada OOP, tapi jelas lebih dapat digunakan kembali daripada kebanyakan kode di luar sana.sumber
Dari tampilan pemrograman fungsional, OOP sebagian besar tentang mengelola negara.
Dalam pemrograman fungsional, Anda dapat dengan mudah memiliki ratusan fungsi yang berguna untuk daftar: http://haskell.org/ghc/docs/6.12.1/html/libraries/base-4.2.0.0/Data-List.html .
Apakah Anda memiliki ratusan metode dalam kelas Daftar? Metode publik dianggap sebagai antarmuka ke keadaan internal yang Anda ingin tetap kecil.
Sayangnya, alih-alih (kembali) menggunakan banyak fungsi kecil, beberapa orang menduplikasi fungsi. Bagi saya itu karena OOP tidak mendorong penggunaan kembali kode sebanyak pemrograman fungsional.
sumber
Bagi saya, ya, tapi tidak sepanjang waktu, dan itu bisa dilakukan dengan cara lain.
Sebagian besar waktu dengan membuat kelas dasar abstrak dan membuat implementasi konkret dari kelas itu.
Juga banyak kerangka kerja yang menggunakan pewarisan untuk menyediakan penggunaan kembali kode (Delphi, Java, .Net hanyalah beberapa yang langsung muncul dalam pikiran).
Itu bukan untuk mengatakan bahwa banyak perpustakaan utilitas dan potongan kode tidak bisa melakukan pekerjaan dengan baik, tetapi ada sesuatu yang menyenangkan tentang hierarki objek yang dirancang dengan baik.
sumber
Dalam pengalaman saya, saya telah lebih berhasil meningkatkan kode "dapat digunakan kembali" melalui fasilitas pemrograman generik (seperti templat C ++) daripada menggunakan prinsip-prinsip OOP seperti hierarki warisan.
sumber
OOP terlalu terbuka untuk digunakan kembali secara efektif.
Ada terlalu banyak cara untuk digunakan kembali. Setiap kelas publik bertanya: "buat contoh baru tentangku!" , setiap metode publik mengatakan: "panggil aku!" , setiap metode yang dilindungi menghasilkan: "timpa saya!" - dan semua cara penggunaan kembali ini berbeda , mereka memiliki parameter yang berbeda, mereka muncul dalam konteks yang berbeda, semua memiliki aturan yang berbeda, bagaimana memanggil / memperluas / menimpanya.
API lebih baik, ini adalah subset ketat dari poin OOP (atau non-oop), tetapi dalam kehidupan nyata, API mengalami kelebihan kapasitas dan terus berkembang, masih ada terlalu banyak titik koneksi. Juga, API yang baik dapat membuat hidup lebih mudah, ini adalah cara terbaik untuk menyediakan antarmuka untuk OOP.
Paradigma datadlow menyediakan antarmuka yang ketat untuk komponen, mereka memiliki port jenis berikut:
Tergantung pada domain, ada beberapa jenis paket, sehingga konsumen dan produsen dapat terhubung jika mereka memiliki port yang sama (atau kompatibel). Bagian yang paling indah dari itu, yang dapat dilakukan secara visual, karena tidak ada parameter atau tweak pada koneksi, mereka benar-benar hanya menghubungkan konsumen dan produsen.
Saya agak tidak jelas, Anda dapat melihat pada tag "dataflow" di StackOverflow , atau Wikipedia "pemrograman datafow" atau Wikipedia "pemrograman berbasis aliran" .
(Juga, saya telah menulis sistem dataflow, di C ++. Jadi OOP dan DF bukan musuh, DF adalah cara organisasi tingkat yang lebih tinggi.)
sumber
Di CommonLisp ada banyak cara untuk mencapai penggunaan kembali:
pengetikan dinamis, membuat kode Anda menjadi umum secara default
abstraksi imperatif, yaitu subrutin
objek-orientasi, dengan pewarisan berganda dan pengiriman ganda
sintaks-abstraksi, kemampuan untuk mendefinisikan konstruksi sintaksis baru atau menyingkat kode boiler-plate
abstraksi fungsional, penutup dan fungsi tingkat tinggi
Jika Anda mencoba untuk membandingkan pengalaman CommonLisp ke bahasa lain Anda akan melihat bahwa fitur utama bahwa kode mereda reuse adalah kehadiran kedua berorientasi objek dan fungsional abstraksi. Mereka lebih komplementer daripada alternatif: tanpa salah satu dari mereka Anda terpaksa menerapkan kembali fitur yang hilang dengan cara canggung. Lihat, misalnya, kelas functor yang digunakan sebagai penutupan dan pencocokan pola untuk mendapatkan metode pengiriman non-extensible.
sumber
- Kevlin Henney
sumber
Saya akan mengambil risiko ejekan dan mengaku, saya hanya menggunakan OOP baru-baru ini. Itu tidak datang kepada saya secara otomatis. Sebagian besar pengalaman saya melibatkan basis data relasional, jadi saya pikir dalam tabel dan bergabung. Ada klaim bahwa lebih baik untuk mempelajarinya dari awal yang menghindari harus mengubah pemikiran Anda ketika datang ke pemrograman. Saya tidak memiliki kemewahan itu dan menolak untuk membatalkan karir saya karena teori menara gading. Seperti yang lainnya, saya akan mencari tahu.
Awalnya saya pikir keseluruhan konsep itu tidak masuk akal. Sepertinya tidak perlu dan terlalu banyak kesulitan. Saya tahu, ini pembicaraan gila. Jelas dibutuhkan tingkat pemahaman tertentu sebelum Anda dapat menghargai manfaat apa pun atau mengabaikannya untuk metode yang lebih baik.
Penggunaan kembali kode membutuhkan kemauan untuk tidak mengulangi kode, pemahaman tentang bagaimana mencapainya, perencanaan awal. Haruskah Anda menghindari menggunakan kembali kode ketika Anda memutuskan Anda memiliki kasus di mana itu tidak layak? Dan tidak ada bahasa yang begitu ketat OO sehingga akan menimbulkan kesalahan ketika ia berpikir Anda seharusnya mewarisi kode dari kelas lain. Paling-paling mereka menyediakan lingkungan yang kondusif untuk mengimplementasikannya.
Saya pikir manfaat terbesar dari OOP adalah penerimaan umum tentang bagaimana kode harus diatur. Yang lainnya adalah saus. Sebuah tim programmer mungkin tidak sepenuhnya setuju tentang bagaimana semua kelas harus disusun, tetapi mereka harus dapat menemukan kode.
Saya telah melihat kode prosedural yang cukup untuk mengetahui bahwa itu bisa di mana saja, dan kadang-kadang ada di mana-mana.
sumber
OOP memberi Anda lebih banyak cara untuk menggunakan kembali kode. Itu semuanya.
sumber
Penggunaan Kembali Horisontal: aspek, sifat, cangkok
Klasik OO terkadang gagal dalam penggunaan kembali kode, khususnya ketika Anda menjadi gila karena tidak memiliki cara yang lebih baik untuk berbagi fungsionalitas aktual antar kelas. Untuk masalah ini, mekanisme penggunaan kembali horisontal telah dibuat, seperti AOP, sifat dan cangkok.
Pemrograman Berorientasi Aspek
Saya menganggap AOP sebagai setengah oranye yang hilang dari OOP. AOP tidak benar-benar diketahui, tetapi telah membuatnya menjadi kode produksi.
Saya akan coba menjelaskannya dalam istilah sederhana: bayangkan Anda dapat menyuntikkan dan memfilter fungsionalitas dengan struktur khusus yang disebut aspek, aspek-aspek ini memiliki "metode" yang menentukan apa dan bagaimana akan dipengaruhi melalui refleksi , tetapi pada waktu kompilasi , proses ini disebut tenun .
Sebuah contoh akan menjadi aspek yang memberitahu "untuk semua metode kelas tertentu yang dimulai dengan get, program Anda akan menulis ke file log data yang didapat dan waktu mendapatkannya".
Tonton dua pembicaraan ini jika Anda ingin lebih memahami AOP:
Ciri & Graft
Ciri - ciri adalah konstruksi lain untuk mendefinisikan kode yang dapat digunakan kembali yang melengkapi OOP, mereka mirip dengan mixin , tetapi lebih bersih.
Daripada menjelaskannya, ada PHP RFC hebat yang menjelaskan keduanya . Ciri datang ke PHP btw, mereka sudah berkomitmen untuk trunk.
Singkatnya
OOP adalah kunci dalam modularitas, tetap, menurut saya dan seperti yang kita kenal sekarang OOP masih belum lengkap .
sumber
OOP Menyediakan seperangkat alat yang berguna yang memungkinkan Anda untuk menulis kode yang dapat digunakan di lebih banyak tempat daripada yang bisa Anda miliki tanpa alat itu. Jika Anda menulis
PrintIt
fungsi yang mengambil objek lama dan memanggilnya.toString()
, Anda akan menggunakan kembali kode itu segera setelah Anda menyebutnya dengan lebih dari satu jenis objek. Dengan alat-alat ini, setiap baris kode melakukan lebih banyak.Pemrograman fungsional sangat panas sekarang di antara para hipsters. Ini memberi Anda seperangkat alat yang terpisah untuk membuat setiap baris kode berbuat lebih banyak. Mungkin tidak lebih baik atau berfungsi, tetapi menyediakan alat lain di kotak alat.
(Ada ide gila untuk seluruh tingkat tambahan penggunaan kembali berorientasi objek: Idenya adalah bahwa kita dapat mendefinisikan satu
Customer
kelas dan menggunakannya dalam setiap aplikasi yang kita tulis. Kemudian aplikasi hanya akan menjadi lem kecil di sana-sini. Ini tidak berfungsi. Tetapi itu tidak berarti OO Gagal, atau bahkan Penggunaan ulang gagal. Jenis dasar penggunaan kembali dalam aplikasi memungkinkan untuk menulis aplikasi yang berbuat lebih banyak, dan untuk menulisnya lebih cepat.)sumber
Membaca posting di atas, beberapa komentar:
sumber
Masalahnya adalah imho yang lebih halus:
Jadi OOP itu sendiri tidak buruk dari pov membuat kode dapat digunakan kembali , tetapi jenis kode yang ditulis menggunakan OOP secara inheren sulit untuk digunakan kembali .
Juga, pemrograman fungsional dapat menghasilkan kode yang lebih dapat digunakan kembali . Tetapi mendapatkan abstraksi yang tepat untuk menulis kode fungsional yang waras sambil memenuhi tenggat waktu mungkin tidak bisa dilakukan. Dan abstraksi "setengah benar" akan lebih mudah untuk mengekspresikan gaya OOP. Dan itu tidak akan cenderung menghasilkan lebih mudah untuk menggunakan kembali kode - tingkat abstraksi yang lebih tinggi berarti bahwa pemahaman kode akan memerlukan investasi dimuka yang lebih tinggi dari kapasitas kognitif terbatas pemrogram.
Sebagai contoh praktis: Kode gim melibatkan banyak keadaan yang bisa berubah, karena ini adalah cara alami untuk berpikir tentang penyandian gim, kecuali gim ini sangat teka-teki / algoritmik, sehingga jelas terstruktur menggunakan OO. Dan tentu saja sulit untuk digunakan kembali. Tetapi kode yang sama, yang berisi pengetahuan yang sama, akan lebih sulit untuk digunakan kembali tanpa OOP . Dan menulis ulang menjadi gaya fungsional mungkin perlu mengubah cara Anda berpikir tentang kode itu, pengetahuan di baliknya. Ya, pengetahuan yang dihasilkan di balik kode akan jauh lebih jelas setelah OO ke FP menulis ulang mungkin ... tapi biayanya bisa sangat besar dan mungkinjenis biaya yang juga harus dibayar oleh orang-orang yang ingin menggunakan kembali kode yang luar biasa cerdas dan abstrak yang Anda dapatkan , sehingga secara paradoksal, orang akhirnya tidak menggunakan kembali kode tersebut, meskipun secara teknis lebih dapat digunakan kembali.
... yang mengarah ke kehalusan terakhir: penggunaan kembali kode adalah tentang antarmuka People | Code , bukan hanya tentang kode. OOP melakukan pekerjaan yang layak untuk melayani antarmuka ini karena memetakan dengan baik dengan berapa banyak orang berpikir tentang berbagai jenis kode yang ditulis saat ini. FP mungkin lebih baik untuk menggunakan kembali kode, tetapi tidak untuk dengan mudah menggunakan kembali jenis kode yang sebenarnya orang perlu tulis saat ini. Ini akan berubah sebagai jenis kode yang perlu kita tulis perubahan.
PS Dan jika ada yang ingin mengatakan bahwa "OO bukan tentang keadaan bisa berubah, Anda juga dapat memiliki OO dengan keadaan tidak berubah" ... Saya menyebutnya "FP menggunakan kelas sebagai ruang nama". Ini bagus ketika bekerja untuk Anda dan menghindari beberapa kekurangan sistem modul beberapa bahasa dan dapat menghasilkan kode yang lebih dapat digunakan kembali. Tapi itu bukan OO;)
sumber