Apakah menciptakan kembali roda benar-benar seburuk itu?

103

Pengetahuan umum dalam pemrograman yang menemukan kembali roda itu buruk atau jahat .

Tapi kenapa begitu?

Saya tidak menyarankan itu bagus. Saya percaya itu salah. Namun, saya pernah membaca sebuah artikel yang mengatakan, jika seseorang melakukan sesuatu yang salah (pemrograman bijaksana) menjelaskan kepada mereka mengapa itu salah, jika Anda tidak bisa, maka mungkin Anda harus bertanya pada diri sendiri apakah itu benar-benar salah.

Itu mengarahkan saya ke pertanyaan ini:

Jika saya melihat seseorang dengan jelas menciptakan kembali roda dengan membangun metode mereka sendiri dari sesuatu yang sudah dibangun ke dalam bahasa / kerangka kerja. Pertama, demi argumen, mari kita asumsikan bahwa metode mereka sama efisiennya dengan metode bawaan. Juga pengembang, menyadari metode bawaan, lebih memilih metodenya sendiri.

Mengapa ia harus menggunakan yang dibangun di atas miliknya sendiri?

JD Isaacks
sumber
16
Ini pertanyaan yang bagus. Saya tidak berpikir orang harus menemukan kembali roda tetapi penting untuk menantang ide-ide ini untuk memastikan mereka bertahan.
Jon Hopkins
4
@ Demian - Itu sebenarnya ide yang cukup bagus. Jika Anda bisa menjelaskannya maka Anda mungkin dibenarkan melakukannya.
Jon Hopkins
2
Dalam semua keputusan, ada baiknya bertanya apa tujuan utama Anda, dan kemudian menyebabkan sub-elemen lainnya untuk mendukung tujuan utama. Jika tujuan utama Anda adalah memberikan produk yang berkualitas tepat waktu, maka menduplikasi kode yang sudah ada kemungkinan akan merusak tujuan ini. Jika tujuan utama Anda adalah membuat perpustakaan yang dipikirkan dengan lebih baik, maka mungkin itu berkontribusi untuk tujuan ini. Jika Anda bekerja untuk orang lain, maka Anda perlu mengajukan pertanyaan dari sudut pandang mereka , bukan pertanyaan Anda sendiri.
gahooa
5
Temukan kembali jika roda yang ada benar-benar tidak melakukan trik untuk kebutuhan spesifik Anda, atau ... jika Anda ingin tahu cara kerja roda! Artikel menarik tentang topik ini: codinghorror.com/blog/2009/02/…
lindes
4
Dikaitkan dengan Douglas Crockford:The good thing about reinventing the wheel is that you can get a round one.
Joel Etherton

Jawaban:

72

Seperti yang pernah saya posting di StackOverflow, menciptakan kembali roda sering kali merupakan pilihan yang sangat baik , bertentangan dengan kepercayaan populer. Keuntungan utama adalah Anda memiliki kendali penuh atas perangkat lunak, yang seringkali penting. Untuk diskusi lengkap, lihat posting asli saya .

Dimitri C.
sumber
14
+1 Poin terpenting adalah sepenuhnya berada di bawah kendali Anda dan Anda tahu itu dari dalam ke luar. Debugging perpustakaan lain dapat menyebabkan sakit kepala besar, jika memungkinkan, dan untuk mengatakan bahwa semua perpustakaan dewasa bebas bug tidak optimis untuk sedikitnya.
Orbling
6
Tim Excel bahkan lebih jauh menulis kompiler mereka sendiri karena mereka tidak menginginkan dependensi eksternal yang dapat mempengaruhi proyek. Ini adalah poin yang valid tetapi seberapa penting kontrol itu adalah pertanyaan utama.
Jon Hopkins
6
+1. Sekali dalam kehidupan saya sebelumnya sebagai programmer MFC / VC ++, kami menggunakan perpustakaan pihak ketiga untuk berbagai komponen GUI, yang ternyata menjadi mimpi buruk total untuk dipertahankan. Hal-hal ini menjadi sangat terkait dengan perangkat lunak dan tidak dapat dihapus (tanpa menghabiskan bulan-bulan yang tidak realistis-yang-kita-tidak-miliki). Saya benar-benar yakin bahwa setiap penghematan waktu awal dari tidak harus menggulung kisi-kisi dan tata letak kita sendiri dihancurkan oleh pesanan besar selama bertahun-tahun karena harus mempertahankan keburukan itu.
Bobby Tables
4
@ Guzica, pilihan yang tidak menguntungkan belum tentu cukup untuk digeneralisasi, dan ada perpustakaan lain yang dipelihara dengan baik dan pilihan yang baik. Pertanyaannya adalah apakah keputusan awal telah diteliti dengan cukup baik?
5
Sisi baiknya, jika Anda menggunakan roda yang sudah ada sebelumnya, Anda biasanya punya BANYAK bantuan, sering kali diindeks dengan baik oleh Google, untuk membantu Anda dalam men-debug-nya.
Dan Ray
83

Tergantung ..

Seperti halnya segalanya, ini tentang konteks:

Ini Baik ketika:

  • Kerangka atau pustaka terlalu berat, dan Anda hanya memerlukan fungsionalitas terbatas. Menggulung versi Anda sendiri yang sangat ringan yang sesuai dengan kebutuhan Anda adalah pendekatan yang lebih baik.
  • Ketika Anda ingin memahami dan mempelajari sesuatu yang kompleks, penggulungan Anda sendiri masuk akal.
  • Anda memiliki sesuatu yang berbeda untuk ditawarkan, sesuatu yang tidak dimiliki implementasi orang lain. Bisa jadi sentuhan baru, fitur baru dll.

Itu buruk ketika:

  • Fungsionalitas sudah ada dan dikenal stabil dan terkenal (populer).
  • Versi Anda menambahkan tidak ada yang baru.
  • Versi Anda memperkenalkan bug atau kendala (mis. Versi Anda tidak aman untuk thread).
  • Versi Anda tidak memiliki fitur.
  • Versi Anda memiliki dokumentasi yang lebih buruk.
  • Versi Anda kurang dari unit test dibandingkan dengan apa yang diganti.
Darknight
sumber
2
Di samping poin pertama Anda (dan terbalik ke keempat Anda), jika roda sulit untuk berurusan dengan atau - lebih buruk lagi - tidak fleksibel, Anda benar-benar dapat memperbaikinya. Ini sering terjadi dengan komponen UI di beberapa area, di mana roda berubah menjadi roda kereta, dan hanya bekerja di satu trek.
Magus
1
Sulit untuk memahami cincin yang benar bagi saya. Saya hanya tidak diarahkan analisis grafik sehingga membuat satu, dan sekarang saya tahu. Sekarang saya merasa yakin untuk menggunakan kerangka kerja
JasTonAChair
1
Saya akan menambahkan angka 4 untuk kolom "Bagus" (meskipun jarang berlaku): jika Anda memahami ruang masalah lebih baik daripada perpustakaan yang ada. Perpustakaan waktu standar Java de facto Joda ditulis karena built-in sulit untuk dikerjakan, dan ditulis ulang sebagai perpustakaan waktu standar de jure Java 8 karena mereka sekarang memahami masalahnya jauh lebih baik daripada ketika mereka menulis waktu joda asli.
Morgen
55

Saya pikir kasus seorang pengembang yang sadar menemukan kembali roda "karena dia lebih suka metodenya sendiri" sangat jarang. Sebagian besar dilakukan karena ketidaktahuan, dan kadang-kadang karena keras kepala.

Apakah semuanya seburuk itu? Iya. Mengapa? Karena roda yang ada kemungkinan besar dibuat dari waktu ke waktu dan telah diuji dalam banyak keadaan dan terhadap banyak jenis data yang berbeda. Pengembang roda yang ada telah menghadapi kasus tepi dan kesulitan yang bahkan tidak bisa dibayangkan oleh reinventor.

Dan Ray
sumber
3
Atau kemalasan - bahwa tidak dapat diganggu untuk pergi dan mencari alternatif atau merasa kurang menarik untuk pergi dan melakukannya untuk menulis kode.
Jon Hopkins
9
Saya telah melihat banyak kasus di mana penemuan kembali roda dilakukan karena kesombongan, dengan sikap bahwa perpustakaan / kerangka kerja xyz hanya untuk programmer yang tidak tahu bagaimana melakukannya dengan "cara yang benar". Heck, saya pernah melihat argumen itu (dalam beberapa cara atau lainnya) di situs SO.
Bill
2
... Yang menciptakan beban pemeliharaan (jenis terburuk) berulang pada pengembang saat ini atau selanjutnya.
gahooa
2
Inilah yang saya lakukan selama bertahun-tahun. Saya akan memutar fitur saya sendiri dalam bahasa karena saya tidak tahu bahwa fungsi itu sudah built-in.
Matchu
1
Sejak menulis posting ini (ya ampun) hampir tiga tahun yang lalu, saya mempekerjakan dan memecat seorang pengembang yang saya gambarkan dalam kalimat pertama sebagai "sangat jarang". Dia bertahan sebulan. Saya akan memberitahunya bagaimana kita melakukan sesuatu di sini dan dia akan berkata "Saya mendengar apa yang Anda katakan". Butuh waktu sebulan untuk mendengar yang tak terkatakan "... tapi itu salah dan aku akan diam-diam melakukan segalanya kecuali itu" di akhir kalimat.
Dan Ray
22

Roda persegi harus diciptakan kembali. Upaya menghisap harus digandakan. Mungkin ada kekurangan dokumentasi untuk metode ini, dan programmer lain merasa lebih mudah hanya menulis sendiri daripada mencoba mencari tahu. Mungkin cara metode ini dipanggil adalah canggung dan tidak cocok dengan idiom bahasa pemrograman.

Tanyakan saja apa kekurangannya.

pengguna8865
sumber
9
+1 Metafora yang baik "roda persegi harus diciptakan kembali" .
Orbling
+1 untuk "Roda persegi harus diciptakan kembali"
Tintu C Raju
17

Secara umum, saya menghindari menciptakan kembali roda jika fungsi yang saya inginkan, atau sesuatu yang mendekati itu, ada di perpustakaan standar bahasa yang saya gunakan.

Namun, jika saya harus menggabungkan perpustakaan pihak ketiga, itu panggilan penilaian tergantung pada seberapa banyak digunakan dan dihargai perpustakaan itu. Maksudku, apakah kita berbicara tentang Boost atau Bob's Kick-ass String-Parsing Tools 1.0?

Bahkan jika perpustakaan umumnya terkenal dan sangat dihargai di seluruh industri, itu masih merupakan ketergantungan pihak ketiga . Pemrogram umumnya memberi penekanan signifikan pada kebajikan penggunaan kembali kode, sementara sering mengabaikan bahaya ketergantungan. Sebuah proyek dengan ketergantungan pihak ketiga yang terlalu banyak kemungkinan akan berantakan dalam jangka panjang karena perlahan-lahan berubah menjadi mimpi buruk pemeliharaan.

Jadi meningkatkan kode yang ada itu baik - tetapi dependensi buruk . Sayangnya, kedua pernyataan ini bertentangan satu sama lain, jadi triknya adalah mencoba menemukan keseimbangan yang tepat. Itu sebabnya Anda perlu mengidentifikasi dependensi yang dapat diterima . Seperti yang saya katakan, segala sesuatu di Perpustakaan Standar bahasa kemungkinan besar merupakan ketergantungan yang dapat diterima. Beranjak dari sana, perpustakaan yang sangat dihormati di seluruh industri juga umumnya dapat diterima (seperti Tingkatkan untuk C ++, atau jQuery untuk Javascript) - tetapi mereka masih kurang diinginkan daripada Perpustakaan Standard karena mereka tidak cenderung kurang stabil dari perpustakaan standar .

Adapun perpustakaan yang relatif tidak dikenal, (misalnya unggahan terbaru di SourceForge) ini adalah dependensi yang sangat berisiko, dan saya biasanya akan merekomendasikan menghindari ini dalam kode produksi, kecuali jika Anda cukup akrab dengan kode sumber untuk mempertahankannya sendiri.

Jadi itu benar-benar semua tindakan penyeimbangan. Tetapi intinya adalah bahwa secara membabi buta mengatakan "Kode menggunakan kembali baik! Menemukan kembali roda buruk!" adalah sikap berbahaya. Manfaat dari pengungkitan kode pihak ketiga harus ditimbang dengan kerugian dari memperkenalkan dependensi.

Charles Salvia
sumber
3
+1. Saya cenderung merasakan hal yang sama. Saya jauh lebih cenderung untuk menemukan kembali roda kecil jika menggunakan roda yang ada akan membuat kerumitan ketergantungan daripada jika roda yang ada sudah ada, mengatur dan menunggu untuk digunakan di lingkungan mana pun di mana saya mungkin membutuhkannya.
dsimcha
14

Jika orang tidak menemukan kembali roda, dunia akan dipenuhi dengan ini .. masukkan deskripsi gambar di sini

Ini dialog dari tempat kerja saya:

- I would like to add some colors to the output of this program.
- Oh, there is this library called Colorama ..

Ada dua opsi: menemukan kembali roda ATAU menggunakan Colorama. Berikut adalah hasil dari setiap opsi:

Menggunakan Colorama

  • Mungkin sedikit lebih cepat untuk berlari
  • Menambahkan ketergantungan pihak ketiga untuk sesuatu yang sepele
  • Anda terus sebodoh sebelumnya menggunakan Colorama

Menemukan kembali roda

  • Anda mengerti bagaimana beberapa program dapat menunjukkan warna
  • Anda belajar bahwa karakter khusus dapat digunakan untuk mewarnai pada terminal apa pun
  • Anda dapat mewarnai dalam bahasa pemrograman apa pun yang mungkin Anda gunakan di masa depan
  • Proyek Anda cenderung rusak

Seperti yang Anda lihat, semuanya tergantung pada konteks. Menemukan kembali roda adalah sesuatu yang saya lakukan sangat sering karena saya ingin dapat dan berpikir untuk diri sendiri dan tidak bergantung pada orang lain yang berpikir untuk saya. Namun jika Anda menjalankan tenggat waktu atau apa yang Anda coba implementasikan sangat besar dan sudah ada, maka Anda lebih baik menggunakan apa yang ada.

Pithikos
sumber
2
+1 tidak setuju dengan Anda 100% tetapi menyukai gambar yang digunakan untuk menyampaikan gagasan.
Tulains Córdova
Jawaban ini agak menghindari bahwa majikan Anda membayar untuk kemewahan Anda menciptakan kembali roda itu untuk manfaat pendidikan Anda sendiri. Mungkin Anda harus melakukannya di waktu Anda sendiri; jika ditanya, majikan Anda mungkin akan mengatakan bahwa dia. / Dia hanya ingin pekerjaan dilakukan dalam waktu secepat mungkin dan jika Colorama melakukan itu, lanjutkan dengan itu.
Neil Haughton
2
@NeilHaughton, seperti yang saya lihat, manfaat pendidikan saya "sendiri" juga bermanfaat bagi majikan saya.
Pithikos
Hmmm ... majikan Anda tentu saja tidak melihatnya seperti itu, dan ia meletakkan roti di atas meja Anda.
Neil Haughton
Perpustakaan Colorama, itu sendiri adalah penemuan kembali roda. Sudah ada antarmuka untuk menampilkan warna di terminal (melalui karakter khusus) dan sebelum keluar orang sudah melakukannya. Pustaka Colorama menciptakan kembali antarmuka cara mencapai tujuan. Jadi pertanyaan di sini adalah lebih lanjut tentang apakah Anda akan menggunakan roda yang seharusnya ditingkatkan, atau apakah Anda menggunakan roda lama dalam proyek Anda? Menciptakan kembali roda dalam hal ini akan membangun Colorama2 yang "meningkatkan" lebih jauh di atas apa yang ditawarkan Colorama.
Ski,
13

Salah satu alasan berguna untuk menemukan kembali roda adalah untuk tujuan pembelajaran - tetapi saya akan merekomendasikan melakukannya pada waktu Anda sendiri. Semakin banyak solusi pra-pengalengan tersedia, dan lebih banyak tingkat abstraksi disediakan, kami menjadi jauh lebih produktif. Kita dapat fokus pada masalah bisnis daripada hal-hal umum yang telah diubah berkali-kali. TAPI, untuk alasan itu, Anda dapat mempertajam keterampilan Anda dan belajar banyak dengan mencoba menerapkan kembali solusi Anda sendiri. Hanya belum tentu untuk penggunaan produksi.

Satu hal lagi - jika kekhawatiran adalah ketergantungan pada perpustakaan pihak ketiga dari perusahaan yang mungkin hilang, pastikan ada opsi untuk mendapatkan kode sumber, atau setidaknya beberapa pilihan lain di luar sana untuk digunakan kembali.

Omong-omong, jika Anda memang memilih untuk mengimplementasikan milik Anda sendiri, hindari melakukan ini untuk kriptografi atau fungsionalitas terkait keamanan lainnya. Alat yang sudah mapan (dan sepenuhnya teruji) tersedia untuk itu, dan di zaman sekarang ini, terlalu berisiko untuk menggulung sendiri. Itu tidak pernah sepadan, dan menakutkan bahwa saya masih mendengar tentang tim yang melakukan ini.

Mark Freedman
sumber
+1 Poin yang sangat bagus pada perspektif pembelajaran, agar dapat menggunakan perpustakaan secara efektif, Anda harus benar-benar mengetahui cara kerjanya. Saya tidak suka kotak hitam menggunakan alat. Juga sangat bagus di pustaka kriptografi, terlalu berisiko untuk memutar skor Anda sendiri.
Orbling
Saya akan menambahkan bahwa jika ada kekhawatiran perpustakaan pihak ketiga mungkin hilang, itu pembenaran yang cukup bagus untuk menulis antarmuka terprogram yang memungkinkan satu perpustakaan dengan mudah ditukar dengan yang lain.
user8865
Poin bagus - kami menggunakan pola adaptor hanya untuk tujuan ini, dan baru-baru ini menyelamatkan kami ketika kami harus menukar perpustakaan FTP pihak ketiga.
Mark Freedman
9

Ada dua jenis efisiensi - pemrosesan / kecepatan (yaitu seberapa cepat dijalankan) yang mungkin cocok dan kecepatan pengembangan yang hampir pasti tidak akan terjadi. Itulah alasan pertama - untuk setiap masalah kompleksitas yang masuk akal di mana solusi yang ada tersedia, hampir pasti akan lebih cepat untuk meneliti dan mengimplementasikan perpustakaan yang ada daripada kode Anda sendiri .

Alasan kedua adalah bahwa perpustakaan yang ada (dengan asumsi itu sudah matang) diuji dan terbukti berfungsi - mungkin dalam skenario yang jauh lebih luas daripada pengembang dan tim uji akan dapat melakukan rutinitas yang baru ditulis melalui dan ini datang pada tanpa usaha.

Ketiga, cara ini lebih mudah untuk didukung. Tidak hanya orang lain yang mendukung dan memperbaikinya (siapa pun yang menulis perpustakaan / komponen), tetapi jauh lebih mungkin bahwa pengembang lain akan terbiasa dengan hal itu dan dapat memahami dan mempertahankan kode ke depan , yang semuanya meminimalkan terus berjalan biaya.

Dan semua itu mengasumsikan kesetaraan fungsional, yang biasanya tidak terjadi. Perpustakaan sering menawarkan fungsionalitas yang menurut Anda berguna tetapi tidak pernah bisa membenarkan bangunan, yang semuanya tiba-tiba tersedia secara gratis.

Ada alasan untuk memutar sendiri - sebagian besar di mana Anda ingin melakukan sesuatu fungsi built-in tidak bisa dilakukan dan di mana ada keuntungan asli yang bisa diperoleh dengan melakukannya, atau di mana opsi yang tersedia tidak matang - tetapi mereka Anda kurang umum daripada banyak pengembang yang Anda yakini.

Selain itu, mengapa Anda ingin menghabiskan waktu untuk memecahkan masalah yang sudah diselesaikan? Ya itu cara yang bagus untuk belajar tetapi Anda tidak harus melakukan itu dengan biaya solusi yang tepat untuk kode produksi yang saya asumsikan sedang kita bicarakan.

Jon Hopkins
sumber
2
Pada baris terakhir Anda: untuk mengetahui bagaimana mereka dipecahkan. Pemrograman tergantung pada pengalaman setelah semua.
Orbling
@Orbling - cukup adil tetapi Anda tidak harus melakukan itu dalam kode produksi dan saya berasumsi itulah yang dimaksud pertanyaan itu. Harus diubah.
Jon Hopkins
@ Jon Hopkins: Kode produksi baik biasanya mengikuti dari pembelajaran, kecuali dilakukan pada waktu Anda sendiri.
Orbling
@Orbling - Saya berpendapat bahwa Anda tidak boleh belajar sesuatu demi belajar dan kemudian memproduksinya. Entah sesuatu kode produksi yang dalam hal ini harus menjadi solusi terbaik, atau itu untuk belajar. Ada saat-saat ketika mereka tumpang tindih tetapi ini tidak akan menjadi salah satu dari mereka karena kecuali jika Anda sendiri benar-benar solusi terbaik.
Jon Hopkins
@ Jon Hopkins: Idealnya ya, tetapi sering kali tidak ada seorang pun di tim yang tahu bagaimana melakukan apa pun itu, sampai pada titik di mana perpustakaan yang tersedia mungkin tidak dapat diservis dengan andal. Belajar, atau "meneliti" seperti kebanyakan orang menyebutnya, adalah suatu keharusan. Ya, itu bukan pembelajaran demi belajar, tetapi belajar untuk menghindari risiko di masa depan.
Orbling
9

Tentu saja menciptakan kembali kemauan, karena ketidaktahuan dan kesombongan bisa menjadi hal yang buruk, tetapi IMHO pendulum telah berayun terlalu jauh. Ada keuntungan luar biasa untuk memiliki roda yang tidak persis apa yang Anda inginkan dan tidak lebih .

Seringkali ketika saya melihat roda yang sudah ada, ia melakukan jauh lebih banyak daripada yang saya butuhkan, menderita efek platform bagian dalam, dan karenanya rumit, atau kehilangan beberapa fitur utama yang saya butuhkan dan itu akan sulit untuk dilakukan. terapkan di atas apa yang sudah ada.

Selain itu, menggunakan roda yang ada sering menambah kendala pada proyek saya yang tidak saya inginkan. Sebagai contoh:

  • Roda yang ada membutuhkan bahasa dan / atau gaya pemrograman yang berbeda dari yang saya lebih suka gunakan.
  • Roda yang ada hanya berfungsi dengan versi lawas dari suatu bahasa (misalnya, Python 2 bukannya Python 3).
  • Di mana ada pertukaran antara efisiensi, fleksibilitas, dan kesederhanaan, roda yang ada membuat pilihan yang suboptimal untuk use case saya. (Saya telah dikenal untuk menemukan kembali bahkan fungsionalitas dari perpustakaan yang awalnya saya tulis sendiri dalam kasus ini. Biasanya itu karena saya menulis versi perpustakaan fungsi menjadi generik dan cukup efisien, ketika saya saat ini membutuhkan sesuatu yang sangat cepat di spesifik saya kasus.)
  • Roda yang ada memiliki ton legacy cruft yang sama sekali tidak berguna dalam kasus kode baru tetapi membuat hidup tetap sulit (misalnya, perpustakaan Java yang saya gunakan yang memaksa saya untuk menggunakan kelas wadah jeleknya karena ditulis sebelum generik, dll.) .
  • Cara roda model yang ada masalah sama sekali berbeda dari apa yang nyaman untuk kasus penggunaan saya. (Misalnya, mungkin lebih mudah bagi saya untuk memiliki grafik diarahkan diwakili oleh objek node dan referensi tetapi roda yang ada menggunakan matriks adjacency atau sebaliknya. Mungkin lebih mudah bagi saya untuk meletakkan data saya dalam urutan kolom utama, tetapi roda yang ada bersikeras pada baris utama atau sebaliknya.)
  • Perpustakaan menambahkan ketergantungan besar, rapuh yang akan menjadi kerumitan utama untuk bangun dan berjalan di mana pun saya ingin menyebarkan kode saya, ketika semua yang saya butuhkan adalah sebagian kecil dari fitur-fiturnya. Di sisi lain, dalam hal ini saya kadang-kadang hanya mengekstrak fitur yang saya inginkan ke perpustakaan baru yang lebih kecil atau hanya menyalin / menempel jika perpustakaan itu open source dan basis kode membuatnya cukup sederhana. (Saya bahkan telah melakukan ini dengan perpustakaan yang relatif besar yang saya tulis sendiri, bukan hanya milik orang lain.)
  • Roda yang ada mencoba untuk secara patuh sesuai dengan beberapa standar yang tidak nyaman dan tidak relevan untuk kasus penggunaan saya.
dsimcha
sumber
Saya pikir ini semua bermuara pada: jika roda sesuai dengan tujuan Anda, gunakan, jika tidak, buat roda baru yang cocok. Hanya saja, jangan bersikap dogmatis tentang hal itu.
Neil Haughton
5

Seringkali saya menggunakan milik saya sendiri karena saya membangunnya sebelum saya menemukan yang sudah ada sebelumnya, dan saya terlalu malas untuk mencari dan mengganti setiap contoh. Juga, saya sepenuhnya memahami metode saya sendiri sementara saya mungkin tidak mengerti yang sudah ada sebelumnya. Dan akhirnya, karena saya tidak sepenuhnya mengerti yang sudah ada saya tidak dapat memverifikasi bahwa itu benar-benar melakukan semua yang saya lakukan saat ini.

Ada banyak yang harus dikodekan, dan saya tidak punya banyak waktu untuk kembali dan mengkode ulang sesuatu kecuali itu berdampak pada produksi.

Bahkan, satu aplikasi web asp yang masih digunakan saat ini memiliki bagan yang berfungsi penuh yang menampilkan data dalam format tabular dan memungkinkan penyortiran / pengeditan, namun ini bukan datagrid. Itu dibangun beberapa tahun yang lalu ketika saya pertama kali belajar asp.net dan tidak tahu datagrid. Saya agak takut pada kode karena saya tidak tahu apa yang saya lakukan saat itu, tetapi bekerja, akurat, mudah dimodifikasi, tidak macet, dan pengguna menyukainya

Rachel
sumber
2
Itu alasan untuk tidak menggantinya, bukan untuk melakukannya sejak awal. Saya berasumsi bahwa Anda tidak akan melakukan hal yang sama sekarang mengetahui bahwa ada alternatif?
Jon Hopkins
@ Jon lol pasti tidak! Dan saya awalnya membaca pertanyaan mengapa seorang pengembang lebih suka metodenya sendiri daripada yang sudah ada sebelumnya. Membaca ulang pertanyaan itu sekarang membuat saya menyadari kebalikan dari pertanyaan itu diajukan, tetapi saya meninggalkan jawabannya di sini karena tampaknya terkait dan mendapat beberapa suara
Rachel
4

Menemukan kembali roda adalah cara yang bagus untuk belajar bagaimana roda bekerja, tetapi itu bukan cara yang baik untuk membangun mobil.

Dima
sumber
4

Saat ini saya bekerja untuk banyak pelit.

Ketika keputusan dibuat antara "membangun atau membeli", alih-alih membuat keputusan rasional berdasarkan ekonomi, para manajer memilih untuk "membangun." Ini berarti bahwa alih-alih membayar beberapa ribu dolar untuk komponen atau alat, kita menghabiskan waktu berbulan-bulan untuk membangun sendiri. Membeli roda dari perusahaan lain membutuhkan biaya yang keluar dari anggaran - yang dihitung dengan bonus akhir tahun yang tidak dikelola dengan baik. Waktu pemrogram gratis dan karenanya tidak dihitung terhadap bonus akhir tahun (dengan manfaat tambahan dari pemrogram untuk tidak menyelesaikan semuanya "tepat waktu"), oleh karena itu roda yang diciptakan kembali adalah roda bebas .

Dalam perusahaan yang rasional, biaya vs manfaat dari pembelian roda yang dibuat oleh orang lain vs menciptakan kembali roda sendiri akan didasarkan pada biaya jangka pendek dan jangka panjang, serta biaya peluang yang hilang karena seseorang tidak dapat membuat widget baru ketika satu menciptakan kembali roda. Setiap hari Anda menghabiskan menciptakan kembali roda adalah hari lain Anda tidak dapat menulis sesuatu yang baru.

Presentasi on build vs buy .
Artikel tentang build vs beli .

Jika saya melihat seseorang dengan jelas menciptakan kembali roda dengan membangun metode mereka sendiri dari sesuatu yang sudah dibangun ke dalam bahasa / kerangka kerja. Pertama, demi argumen, mari kita asumsikan bahwa metode mereka sama efisiennya dengan metode bawaan. Juga pengembang, menyadari metode bawaan, lebih memilih metodenya sendiri.

Mengapa ia harus menggunakan yang dibangun di atas miliknya sendiri?

Versi built-in akan memiliki lebih banyak orang yang menggedornya - sehingga menemukan dan memperbaiki lebih banyak bug daripada yang bisa dilakukan oleh kode homebrew Anda.

Akhirnya, ketika pengembang lokal Anda pergi, dan orang lain harus menjaga kode yang ia tulis, kode itu akan benar-benar diperbarui dan diganti dengan apa yang ada dalam kerangka kerja. Saya tahu ini akan terjadi karena majikan saya saat ini memiliki kode yang telah dimigrasikan ke versi VB yang lebih baru selama bertahun-tahun (produk tertua telah ada di pasaran selama sekitar 20 tahun) dan inilah yang telah terjadi. Pengembang dengan pekerjaan terlama di kantor saya sudah 17 tahun di sini.

Tangurena
sumber
Agar adil, kadang-kadang versi "standar" diletakkan di sana sebagai penemuan kembali dari apa yang kebanyakan orang lakukan sebelum versi standar dikembangkan. TKI yang standar dimaksudkan untuk menjadi "grand reinvention grand". Tetapi beralih ke versi standar, teruji dengan baik, jauh lebih kuat dan bug-diperbaiki dapat menyebabkan bug, karena kode aplikasi Anda membuat asumsi yang benar untuk versi non-standar lama Anda, tetapi salah untuk yang standar baru.
Steve314
1
Dalam perusahaan yang rasional, jika diputuskan bahwa vendor lock-in dapat diterima, perusahaan (sebagai pembeli dan bergantung pada penawaran penyedia) perlu membangun hubungan bisnis yang baik dengan penyedia, serta melakukan lindung nilai terhadap berbagai kecelakaan bisnis. Contoh: penolakan untuk memberikan dukungan / memperbaiki bug, kenaikan harga, mengubah ketentuan kontrak, gugatan sembrono, atau meninggalkan bisnis sama sekali. Lindung nilai ini juga merupakan bagian dari biaya, dan seringkali diabaikan. (Sama seperti biaya pengembangan in-house diabaikan). Catatan: Biaya ini tidak ada pada penawaran bawaan.
rwong
Apakah Anda tidak lupa bahwa majikan pelit sesat Anda secara efektif memberi Anda lebih banyak pekerjaan berbayar daripada yang seharusnya Anda miliki? Anda seharusnya mendorong mereka daripada mengeluh tentang hal itu!
Neil Haughton
4

Hal tentang menciptakan kembali roda adalah bahwa kadang-kadang tidak ada roda standar yang tersedia untuk melakukan apa yang Anda butuhkan. Ada banyak roda bagus di luar sana, dalam banyak ukuran, warna, bahan, dan mode konstruksi. Tetapi beberapa hari Anda hanya perlu memiliki roda yang benar-benar ringan yang terbuat dari aluminium anodized berwarna hijau, dan tidak ada yang membuatnya. Dalam hal ini, Anda HARUS membuatnya sendiri.

Nah, itu bukan untuk mengatakan bahwa Anda harus membuat roda sendiri untuk setiap proyek - kebanyakan hal dapat menggunakan bagian standar dan lebih baik untuk itu. Tetapi setiap sekarang dan kemudian, Anda menemukan bahwa bagian standar tidak berfungsi, sehingga Anda membuat bagian Anda sendiri.

Yang paling penting adalah mengetahui KAPAN membuat milik Anda sendiri. Anda harus memiliki gagasan yang baik tentang apa yang dapat dilakukan oleh suku cadang standar, dan apa yang tidak bisa mereka lakukan, sebelum Anda mulai merancang sendiri.

Michael Kohne
sumber
4

Apakah menemukan kembali roda atau tidak merupakan hal biaya / manfaat. Biaya cukup jelas ...

  • Diperlukan banyak waktu untuk melakukan reinventing.
  • Bahkan lebih banyak waktu untuk mendokumentasikan apa yang Anda temukan.
  • Anda tidak dapat mempekerjakan orang yang sudah mengerti apa yang Anda temukan.
  • Terlalu mudah untuk menemukan kembali sesuatu yang buruk, menyebabkan biaya berkelanjutan untuk masalah yang disebabkan oleh desain yang buruk.
  • Kode baru berarti bug baru. Kode lama biasanya sudah menghilangkan sebagian besar bug, dan mungkin memiliki solusi halus untuk masalah yang tidak Anda sadari dan karena itu tidak dapat bekerja di sekitar dalam desain baru.

Yang terakhir adalah penting - ada posting blog di suatu tempat yang memperingatkan tentang kecenderungan untuk "membuang kode lama dan mulai dari awal" dengan dasar bahwa banyak kesalahan lama yang tidak Anda pahami sebenarnya adalah perbaikan bug yang penting. Ada kisah peringatan tentang Netscape, IIRC.

Keuntungannya bisa ...

  • Kemampuan untuk menambahkan fitur yang tidak dimiliki perpustakaan yang ada. Sebagai contoh, saya memiliki wadah yang "mempertahankan" contoh iterator / kursor mereka. Sisipan dan penghapusan tidak membatalkan iterator. Iterator yang menunjuk ke vektor akan terus menunjuk ke item yang sama (bukan indeks yang sama) terlepas dari sisipan dan penghapusan sebelumnya dalam vektor. Anda tidak bisa melakukannya dengan kontainer C ++ standar.
  • Desain yang lebih khusus menargetkan kebutuhan khusus Anda dan menghormati prioritas Anda (tetapi waspadai kecenderungan ke arah efek platform-dalam).
  • Kontrol penuh - beberapa pihak ketiga tidak dapat memutuskan untuk mendesain ulang API dengan cara yang berarti Anda harus menulis ulang setengah aplikasi Anda.
  • Pemahaman lengkap - Anda telah mendesainnya seperti itu, jadi semoga Anda benar-benar memahami bagaimana dan mengapa Anda melakukannya.
  • EDIT Anda dapat mempelajari pelajaran dari perpustakaan lain tanpa terjebak dalam perangkap yang sama dengan menjadi selektif tentang bagaimana Anda meniru mereka.

Satu hal - menggunakan perpustakaan pihak ketiga dapat dihitung sebagai menciptakan kembali roda. Jika Anda sudah memiliki perpustakaan kuno, yang sudah digunakan, dan teruji dengan baik, pikirkan dengan cermat sebelum membuangnya untuk menggunakan perpustakaan pihak ketiga. Ini mungkin merupakan ide yang bagus dalam jangka panjang - tetapi mungkin ada banyak pekerjaan dan banyak kejutan buruk (dari perbedaan semantik antara perpustakaan) sebelum Anda sampai di sana. Sebagai contoh, pertimbangkan efek saya beralih dari wadah saya sendiri ke yang standar perpustakaan. Terjemahan naif dari kode panggilan tidak akan memungkinkan fakta bahwa kontainer perpustakaan standar tidak mempertahankan iteratornya. Kasus di mana saya menyimpan iterator untuk nanti sebagai "bookmark" tidak dapat diimplementasikan menggunakan terjemahan sederhana sama sekali - I '

Steve314
sumber
3

Jika ada komponen kerja yang melakukan apa yang Anda butuhkan, mengapa menghabiskan waktu menulis dan men-debug versi Anda sendiri? Demikian pula, jika Anda sudah menulis kode untuk memenuhi fungsi yang sama sebelumnya, mengapa menulis ulang?

Joel menulis sebuah artikel tentang Tidak-diciptakan-di sini yang berbicara banyak tentang kapan menulis ulang kode dan perangkat lunak tidak dan tidak berguna.

Dave
sumber
3

Menciptakan kembali roda dapat menjadi cara yang bagus untuk belajar bagaimana sesuatu bekerja - dan saya sarankan menciptakan kembali untuk tujuan itu pada waktu Anda sendiri - tetapi ketika menulis aplikasi mengapa menemukan kembali jika ada solusi mapan yang sudah melakukan hal yang sama?

Sebagai contoh, saya tidak akan pernah menulis kode JavaScript dari awal; sebaliknya saya akan mulai dengan jQuery dan membangun aplikasi saya di atas kerangka itu.

Justin Ethier
sumber
3

Aturan praktis saya:

Menciptakan kembali roda adalah hal yang baik ketika Anda baru belajar. Jika Anda memiliki tenggat waktu, Anda mungkin ingin menggunakan roda yang ada.

John
sumber
3

Menjadi "buruk" atau bahkan "jahat" adalah kata-kata yang agak kuat.

Seperti biasa, selalu ada alasan untuk memilih implementasi pribadi daripada implementasi internal. Di masa lalu program C mungkin menemukan bug di pustaka runtime, dan karena itu hanya perlu menyediakan implementasinya sendiri.

Ini tidak berlaku untuk program Java karena JVM didefinisikan dengan sangat ketat, tetapi beberapa algoritma masih sangat sulit untuk diperbaiki. Sebagai contoh, Joshua Bloch menjelaskan bagaimana algoritma pencarian biner sederhana yang sederhana di perpustakaan Java runtime berisi bug, yang membutuhkan waktu sembilan tahun untuk muncul:

http://googleresearch.blogspot.com/2006/06/extra-extra-read-all-about-it-nearly.html

Itu ditemukan, diperbaiki dan didistribusikan di distribusi Jawa masa depan.

Jika Anda menggunakan pencarian biner bawaan, Anda hanya menghemat waktu dan uang dengan meminta Sun melakukan kerja keras untuk menemukan, memperbaiki, dan mendistribusikan perbaikan bug ini. Anda dapat memanfaatkan pekerjaan mereka hanya dengan mengatakan "Anda memerlukan setidaknya Java 6 pembaruan 10".

Jika Anda menggunakan implementasi Anda sendiri - yang kemungkinan besar akan mengandung kesalahan ini juga - Anda pertama-tama membutuhkan bug untuk memanifestasikan dirinya. Mengingat bahwa yang satu ini hanya menunjukkan pada dataset BESAR, itu pasti terjadi dalam produksi di suatu tempat, artinya setidaknya satu dari pelanggan Anda akan terpengaruh dan kemungkinan besar kehilangan uang sungguhan saat Anda menemukan, memperbaiki, dan mendistribusikan perbaikan bug.

Jadi, sangat sah untuk memilih implementasi Anda sendiri, tetapi alasannya lebih baik benar-benar baik, karena itu pasti lebih mahal daripada meningkatkan pekerjaan orang lain.

pengguna1249
sumber
+1 untuk mengandalkan platform untuk menyebarkan perbaikan bug. Di sisi lain, tergantung pada vendor platform untuk memutuskan apakah akan mendistribusikan perbaikan bug. Vendor yang berbeda dapat memilih: (1) mendistribusikan perbaikan bug, gratis; (2) menahan perbaikan bug sampai versi utama di-upgrade; (3) mendistribusikan perbaikan bug ke pengguna versi terbaru, tetapi menolak versi sebelumnya (4) menolak untuk memperbaiki sama sekali, mengklaim bahwa itu dapat "menyebabkan ketidakcocokan luas" dan "hanya mempengaruhi pengguna terbatas".
rwong
@ rwong, jika Anda menemukan bug dalam rutin bawaan, taruhan terbaik Anda adalah menyediakan versi perbaikan Anda sendiri. Ini berada di bawah "alasan yang sangat bagus untuk melakukannya".
ørn: Maksud saya adalah bahwa selain vendor yang baik hati yang Anda sebutkan, ada juga jenis vendor lainnya.
rwong
@ rwong, dalam hal ini yang memenuhi syarat untuk "alasan yang sangat bagus untuk memilih implementasi pribadi".
3

Baru-baru ini saya membuat blog pemikiran saya tentang topik ini. Untuk meringkas:

  1. Itu hampir selalu jahat untuk membangun Anda sendiri, terutama benar jika itu adalah fungsi yang dibangun ke dalam bahasa. Tetapi jika Anda mengevaluasi kerangka kerja yang belum matang / dipelihara dengan buruk / tidak terdokumentasi dengan baik yang Anda temukan di Internet terhadap kemungkinan menulis sendiri, itu bisa jadi tidak ada gunanya.

  2. Saya pikir menciptakan kembali roda adalah analogi yang cukup mengerikan untuk anti-pola perangkat lunak. Ini menyiratkan bahwa solusi asli tidak pernah dapat diperbaiki. Itu omong kosong. Roda yang disebut dapat menjadi usang dalam semalam, atau pemiliknya bisa berhenti memeliharanya. Roda memiliki nilai berbeda di setiap sistem tempat ia digunakan. Jadi, seringkali sangat mungkin untuk menciptakan roda yang lebih baik.

  3. Salah satu manfaat utama membuat kerangka kerja Anda sendiri adalah Anda tidak perlu bertanggung jawab atas bug orang lain. (Ini adalah filosofi Amazon .) Pikirkan seperti ini: mana yang lebih baik untuk diceritakan pada pelanggan? -

    "Situs web kami rusak. Itu adalah kesalahan orang lain, dan kami telah mencatat bug dengan penciptanya. Tidak ada yang bisa kami lakukan selain menunggu. Kami akan terus memberi Anda informasi terbaru."

    "Situs web kami rusak, dan kami dapat segera memperbaikinya."

realworldcoder
sumber
0

Mungkin sama efisiennya, tetapi apakah kuat? Saya pikir alasan paling menarik untuk menggunakan pustaka daripada menggulirkan pustaka Anda sendiri adalah bahwa kerangka kerja ini memiliki begitu banyak orang yang menggunakannya sehingga mereka dapat menemukan dan memperbaiki bug dengan cepat. Pustaka yang dikembangkan in-house, sementara mereka dapat menyediakan fungsionalitas sebanyak (atau lebih), tidak dapat bersaing dengan pustaka dengan jutaan pengguna untuk menyediakan pengujian di hampir setiap kasus penggunaan. Anda tidak bisa mengalahkan pengujian semacam itu di rumah.

Michael K.
sumber
0

Yah, metodenya sendiri yang seefisien kerangka kerja akan sangat langka karena sebagian besar kerangka kerja masih memiliki bug dan tidak ada kerangka kerja yang dapat memberi Anda solusi out of the box. Sebagian besar programmer yang tidak bisa berpikir tidak akan pernah mencoba menulis apa pun di tingkat kerangka kerja; mereka hanya akan mencari Google untuk solusi yang sudah jadi. Setiap programmer yang bijak akan terlebih dahulu melihat apakah ada kerangka kerja gratis yang memiliki fungsi yang dia butuhkan, dan kemudian menulis solusinya sendiri jika tidak ada. Terkadang terlalu sulit untuk menjelaskan situasi proyek saat ini dan pengembang adalah juri terbaik.

Menemukan kembali roda bukanlah hal yang buruk, itu adalah pernyataan yang dibuat oleh orang-orang malas untuk menghindari kerja keras. Bahkan penulis kerangka pun menemukan kembali; seluruh framework .Net diciptakan kembali untuk melakukan apa yang COM tawarkan.

Akash Kava
sumber
0

Meskipun mungkin tidak sopan bagi sebagian orang, saya selalu menganggap istilah ini tidak paham ketika digunakan oleh segala bentuk insinyur atau merujuk pada topik membuat atau merancang sesuatu. Kenyataannya, saya tidak dapat menahan diri untuk melihatnya sebagai sesuatu yang tidak jujur ​​ketika mempertimbangkan tekanan untuk berinovasi di dunia yang serba cepat saat ini. Mengulangi diri Anda sendiri (atau mengabaikan solusi yang sudah ada sebelumnya) tidak pernah bijaksana, tetapi sungguh, ada alasan mengapa kita tidak semua masih menatap layar hitam penuh dengan huruf hijau.

Saya mengerti "Jika tidak rusak jangan memperbaikinya", meskipun saya kira kalimat seperti itu mungkin terdengar bodoh bagi sebagian orang. Namun dengan upaya saat ini untuk menemukan kembali roda untuk kebutuhan perjalanan ruang angkasa, balap, pengiriman, dll, "jangan menemukan kembali roda" juga cukup bodoh, dan tidak ada yang dekat sepintar kedengarannya.

Latar belakang saya terdiri dari memimpin banyak proyek dan saya harus bekerja dengan banyak pekerja magang dan bentuk-bentuk pengembang hijau lainnya, dan saya harus menangani banyak pertanyaan naif yang beberapa orang sebut 'bodoh', dan juga harus mengalihkan orang dari mengejar kelinci. keutuhan di luar lingkup tugas mereka. Namun, saya tidak akan pernah mencegah inovasi atau kreativitas, dan telah melihat hal-hal besar datang dari 'menciptakan kembali roda'.

Jawaban aktual saya terhadap pertanyaan: Hanya ada dua situasi yang membuat penemuan kembali roda adalah hal yang buruk:

  1. Jika tidak benar-benar dibutuhkan
  2. Jika orang lain yang melakukannya ketika Anda bisa melakukannya

Sunting: Saya dapat melihat dengan suara turun drive-by bahwa saya pasti telah menyinggung beberapa. Satu hal yang ingin saya tambahkan adalah frasa ini selalu mengesalkan saya. Saya mengerti bahwa dua sen saya mungkin terdengar agak trollish, tetapi saya tidak punya niat untuk troll, menyebabkan kebakaran, atau menyinggung.

ClosetGeek
sumber
0

Argumen tentang "reinventing a wheel" sering digunakan dalam konteks yang salah memilih untuk menggunakan perpustakaan tapi itu hampir tidak sama.

Katakanlah saya sedang mengevaluasi perpustakaan 'formulir-plus', yang baru-baru ini menjadi populer dan membantu menangani formulir. Ini memiliki halaman arahan yang bagus, grafik keren modern, dan -cult- (komunitas maksudku) di sekitarnya yang bersumpah bagaimana membuat formulir menjadi hebat lagi. Tetapi "bentuk-plus" adalah abstraksi di atas "bentuk". "Bentuk" itu mungkin tetapi rumit untuk dihadapi, jadi abstraksi yang membuatnya lebih mudah menjadi populer.

Abstraksi baru terjadi setiap saat. Sulit untuk membandingkannya dengan roda. Ini lebih seperti perangkat kontrol baru dan manual baru untuk perangkat apa pun yang sudah sangat rumit yang harus Anda jalankan.

Penilaian perangkat baru ini "formulir-plus" akan terlihat berbeda tergantung pada pengalaman pribadi. Jika saya tidak pernah membuat formulir sebelumnya maka "formulir-plus" akan sangat menarik karena lebih mudah untuk memulai. Kelemahannya adalah jika "bentuk-plus" ternyata abstraksi bocor saya masih perlu belajar "bentuk". Jika saya membangun formulir tanpa "formulir-plus" maka saya perlu memperhitungkan waktu bahwa saya perlu mempelajari alat baru. Terbalik adalah bahwa saya sudah tahu "bentuk" jadi saya tidak takut abstraksi di atasnya. Manfaat jangka pendek seringkali akan lebih besar untuk pemula baru karena mungkin tidak akan ada perpustakaan baru jika tidak memperbaiki sesuatu. Manfaat jangka panjang akan sangat bervariasi pada kualitas abstraksi, tingkat adopsi,

Setelah mengevaluasi dengan seksama manfaat dan negatif dari menggunakan abstraksi baru "formulir-plus" vs menggunakan "bentuk" tulang kosong, saya membuat keputusan. Keputusan sangat didasarkan pada pengalaman pribadi saya dan orang yang berbeda akan membuat keputusan berbeda. Saya mungkin telah memilih untuk menggunakan "bentuk" tulang kosong. Mungkin nanti dalam bentuk waktu-plus telah mendapatkan lebih banyak gerakan di belakangnya dan menjadi standar de facto. Dan mungkin implementasi saya sendiri dari waktu ke waktu menjadi berbulu dan mulai mencakup banyak apa bentuk-plus sekarang lakukan. Orang-orang yang datang pada saat ini akan tertarik untuk mengkritik bahwa saya ingin menciptakan kembali roda dan saya seharusnya menggunakan perpustakaan yang ada. Tetapi juga mungkin bahwa pada saat saya harus membuat keputusan tentang "bentuk-plus" ada juga beberapa alternatif lain untuk "bentuk-plus",

Pada akhirnya memilih alat yang tepat adalah keputusan yang rumit untuk dibuat dan "reinvention of wheel" bukanlah perspektif yang sangat membantu.

Main ski
sumber
-1

Saya menulis sedikit artikel tentang ini - http://samueldelesque.tumblr.com/post/77811984752/what-re-inventing-the-wheel-can-teach-you

Dalam pengalaman saya, penemuan kembali sebenarnya hebat - meskipun sangat panjang dan membosankan. Saya akan mengatakan, jika Anda tidak tahu persis model pemrograman yang akan Anda gunakan, maka tulis sendiri (jika Anda punya waktu dan energi). Ini akan mengajarkan Anda tentang apa sebenarnya model-model pemrograman tersebut dan Anda akan menjadi programmer yang lebih baik pada akhirnya. Tentu saja, jika Anda bekerja untuk klien dan hanya perlu mendapatkan sesuatu dengan cepat, Anda mungkin hanya ingin melakukan riset dan menemukan perangkat lunak yang tepat untuk Anda.

Samuel Delesque
sumber