Apakah Anda pikir Pemrograman Berorientasi Objek adalah solusi untuk kompleksitas. Mengapa? Topik ini mungkin agak kontroversial tetapi niat saya untuk mengetahui jawaban Mengapa dari para ahli di sini!
Apakah Anda pikir Pemrograman Berorientasi Objek adalah solusi untuk kompleksitas. Mengapa? Topik ini mungkin agak kontroversial tetapi niat saya untuk mengetahui jawaban Mengapa dari para ahli di sini!
Jawaban:
Tidak ada solusi untuk kompleksitas.
Dalam "The Mythical Man-Month", Fred Brooks membahas perbedaan antara kerumitan yang tidak disengaja dan esensial dalam pemrograman. Kompleksitas tidak disengaja disebabkan oleh alat dan metode kami, seperti harus menulis dan menguji kode tambahan dalam bahasa karena kami tidak dapat mengekspresikan ide-ide kami secara langsung, dan hal-hal seperti itu. Metode dan teknik baru dapat mengurangi kompleksitas yang tidak disengaja. Saya dapat menulis program lebih cepat dan lebih baik daripada yang saya bisa dua puluh lima tahun yang lalu, karena saya memiliki bahasa dan alat yang lebih baik.
Kompleksitas esensial datang dari kenyataan bahwa apa yang kami coba lakukan dengan pemrograman pada dasarnya rumit, dan bahwa ada kompleksitas yang tidak dapat direduksi. "Esensial", dalam konteks ini, berarti "berkaitan dengan esensi dari hal" daripada "sangat diperlukan".
Oleh karena itu, ia mengklaim bahwa tidak akan ada peluru perak, bahwa menulis perangkat lunak akan terus menjadi sulit.
Saya sangat menyarankan Anda membaca bukunya: khususnya, saya merekomendasikan edisi Peringatan Perak, dengan esai tambahan "No Silver Bullet". Dalam hal itu, ia meninjau solusi yang diusulkan untuk kompleksitas dan mempertimbangkan dampaknya. (Apa yang menurutnya paling efektif adalah perangkat lunak pembungkus - tulis sesuatu yang kompleks sekali, dan jual ribuan atau jutaan salinan.)
Sekarang, pemrograman berorientasi objek membantu, ketika dilakukan dengan benar, dengan menciptakan abstraksi dan menyembunyikan kompleksitas. Objek kelas memiliki perilaku tertentu yang ditentukan yang dapat kita alasankan, tanpa memedulikan kompleksitas implementasi. Kelas yang ditulis dengan benar memiliki sambungan rendah satu sama lain, dan membagi-dan-taklukkan adalah cara terbaik untuk menangani kompleksitas jika Anda bisa lolos begitu saja. Mereka juga memiliki kohesi yang tinggi, dalam arti mereka adalah seperangkat fungsi dan data yang berhubungan sangat erat satu sama lain.
Saya berharap Anda akan mendapatkan jawaban yang lebih baik segera, tapi ini yang sederhana:
OOP membantu * dengan kerumitan dengan memodelkan perangkat lunak dengan cara yang lebih dekat dengan cara kita memodelkan segala sesuatu yang lain di dunia. Secara umum, lebih mudah untuk membayangkan objek bola berinteraksi dengan objek dinding daripada membayangkan serangkaian rutinitas dan struktur data untuk melakukan hal yang sama, karena lebih dekat dengan cara kita berinteraksi dengan dunia nyata.
* Karena tidak ada yang bisa 'menyelesaikan' kompleksitas
Saya pikir definisi arus utama OOP saat ini bukan solusi yang baik untuk mengelola kompleksitas.
Jika Anda kembali ke akarnya, saya percaya Alan Kay sangat dipengaruhi oleh "cadel".
Karena Lisp belum dirusak oleh adopsi arus utama, ia mungkin berhasil melestarikan nilai-nilai intinya. Jadi saya pikir melihat bagaimana cisp mengatasi masalah kompleksitas ini dapat memberi kita wawasan, dan kita dapat menggunakannya sebagai dasar untuk menilai seberapa berguna OOP dalam menangani kompleksitas.
Jika Anda melihat pada akhir "Kuliah 3a: Henderson Escher Contoh" dari SICP , Hal Abelson mengusulkan bahwa kompleksitas dikelola bukan dengan memecah tugas menjadi subtugas yang lebih kecil, tetapi dengan menciptakan lapisan abstraksi. Pada level tertinggi, Anda mengekspresikan solusi untuk masalah rumit dalam hal solusi ke level abstraksi yang lebih rendah.
Saya pikir OOP awalnya dimaksudkan sebagai mekanisme untuk membuat lapisan-lapisan abstraksi ini.
Sayangnya saat ini, OOP (ab) digunakan untuk menulis kode / struktur spaghetti.
Saya akan membuat contoh: permainan multi-pemain FPS.
Pada level tertinggi, gim ini bekerja dengan menyuruh sekelompok pemain berlarian di peta dan saling menembak menggunakan senjata.
Di tingkat bawah berikutnya, kita harus berbicara tentang peta dan senjata serta pemain. Mungkin kita bisa membicarakannya sebagai objek fisik yang berinteraksi dalam dunia game.
Di tingkat bawah berikutnya, kita dapat berbicara tentang bagaimana benda berinteraksi secara fisik (gerakan, tabrakan, dll).
Dan seterusnya dan seterusnya.
Apa artinya ini, (dan saya semacam mengutip dari SICP ..), adalah bahwa pada setiap lapisan, kita tidak hanya memecahkan masalah khusus tertentu, tetapi kelas masalah yang semacam jatuh di lingkungan masalah kita sedang mencoba untuk memecahkan. Jadi, jika ada sedikit perubahan dalam deskripsi masalah, kemungkinan besar hanya membutuhkan sedikit perubahan dalam solusi.
Jadi, cara bijak untuk menggunakan OOP adalah dengan membuat lapisan abstraksi, pada setiap tingkat abstraksi, Anda memecahkan masalah yang ada dengan menggunakan "objek" dari tingkat yang langsung di bawah.
Inilah bagian yang saya kutip dari kuliah: http://www.youtube.com/watch?v=CYtrfncMqHQ
Seperti biasa saya tidak setuju dengan semua orang. Jauh dari memberi Anda alat untuk mengelola kompleksitas, OOP menciptakan sejumlah besar kompleksitas karena itu adalah paradigma yang tidak memadai dan palsu secara matematis. Itu membingungkan programmer tanpa akhir, untuk mencoba memodelkan hal-hal dengan OOP yang tidak dapat dimodelkan dengan OOP.
Dalam pandangan saya karya mani di sini adalah Konstruksi Perangkat Lunak Berorientasi Obyek Meyer. Ini merinci serangkaian persyaratan, termasuk yang saya anggap penting: Prinsip Terbuka-Tertutup. Ini mengatakan bahwa sesuatu harus terbuka untuk ekstensi tetapi ditutup untuk digunakan, pada saat bersamaan.
Meyer melanjutkan untuk mendapatkan Orientasi Objek dari persyaratan ini, sebagaimana diwujudkan dalam Eiffel. Enkapsulasi memberikan penutupan, keterbukaan warisan, dan "hal" yang disebutkan adalah kelas.
Saya menganggap karya ini sebagai ilmu yang baik karena Meyer terbukti salah, dan mungkin karena kualitas karyanya, untuk menunjukkan kesalahan dan memperbaikinya.
Kesalahannya adalah membuat kelas, atau tipe, unit modularitas. Itu salah, dan bisa dibuktikan begitu. Bahkan Meyer mengakui masalah (disebut masalah kovarians), bahwa OOP tidak dapat menangani hubungan arity lebih tinggi dari satu (yaitu, OOP berfungsi dengan baik untuk properti tetapi gagal pada hubungan biner). Di Eiffel, masalah ini mengakibatkan ketidaksempurnaan dalam sistem tipe!
Solusinya cukup jelas. Unit modularitas harus lebih besar dari satu tipe. Itu harus terdiri dari beberapa jenis, dan metode yang menghubungkannya.
Tidak mengherankan bahwa model abstraksi ini didukung oleh teori matematika abstraksi, yaitu teori kategori: jenis adalah objek dari suatu kategori, dan metode (fungsi) adalah panah.
Dengan model ini, representasi dari beberapa tipe diketahui dari serangkaian fungsi. Representasi disembunyikan dari publik, jadi ini adalah enkapsulasi, tetapi kami menggunakan modul, bukan kelas.
Standard Meta-Language (SML) dan Ocaml didasarkan langsung pada model ini. Ocaml juga memiliki kelas dan OOP: tidak sia-sia karena OOP memberi Anda pengiriman properti, alias pengikatan dinamis. Namun sebagian besar masalah dunia nyata melibatkan hubungan dan tidak mengherankan kelas tidak banyak digunakan dalam Ocaml.
Tidaklah mengejutkan bahwa pewarisan sama sekali tidak digunakan di pustaka template C ++ Standard.
Fakta sederhananya adalah, OOP tidak memberi Anda alat yang tepat untuk menangani kerumitan, bahkan OOP tidak memberi Anda alat untuk menangani masalah yang sangat sederhana, melainkan telah menyesatkan dan membingungkan dua generasi programmer. Jauh dari membantu, OOP adalah hal yang paling Jahat dan Buruk yang terjadi pada pemrograman sejak C, Fortran dan Cobol mulai lelah.
Pemrograman berorientasi objek memiliki akar yang dapat dilacak hingga 1960-an. Karena perangkat keras dan lunak menjadi semakin kompleks, pengelolaan seringkali menjadi perhatian. Para peneliti mempelajari cara-cara untuk menjaga kualitas perangkat lunak dan mengembangkan pemrograman berorientasi objek sebagian untuk mengatasi masalah-masalah umum dengan sangat menekankan unit-unit logika pemrograman yang terpisah dan dapat digunakan kembali.
Program berorientasi objek dengan demikian dapat dipandang sebagai kumpulan objek yang berinteraksi, sebagai lawan dari model konvensional, di mana suatu program dipandang sebagai daftar tugas (subrutin) yang harus dilakukan. Dalam OOP, setiap objek mampu menerima pesan, memproses data, dan mengirim pesan ke objek lain. Setiap objek dapat dilihat sebagai 'mesin' independen dengan peran atau tanggung jawab yang berbeda. Tindakan (atau "metode") pada objek-objek ini terkait erat dengan objek itu sendiri.
http://en.wikipedia.org/wiki/Object-oriented_programming
Pemisahan keprihatinan ini, bersama dengan fitur-fitur lain dari Orientasi Objek seperti polimorfisme, pewarisan, penyampaian pesan, decoupling dan enkapsulasi, menyediakan kerangka kerja logis dan konseptual yang dengannya kompleksitas program besar dapat dikelola dengan cara yang sangat efektif.
Ada banyak jenis kompleksitas untuk pengembangan perangkat lunak. Pada level pemrograman, OOP berupaya mengatasi kompleksitas dengan menggunakan objek dan kelas untuk memodelkan domain masalah. Seorang guru terkenal mengatakan penyelesaian masalah hanya mewakili masalah sehingga solusinya adalah representasi itu sendiri. Oleh karena itu, dengan abstraksi menggunakan kelas, enkapsulasi menggunakan pengubah akses dan metode, pewarisan untuk menentukan hubungan dan penggunaan kembali, komposisi dalam membangun hubungan dan kolaborasi antara kelas, polimorfisme sebagai sarana untuk menyederhanakan penentuan perilaku yang berbeda di objek yang sama, kompleksitas dapat dikelola.
Ada juga cara lain untuk mengelola kompleksitas perangkat lunak, misalnya, pemrograman Logika (Prolog) dan Fungsional (Haskell).
Pada tingkat yang lebih tinggi daripada pemrograman, kita membutuhkan Pola Desain dan Prinsip untuk memandu OOP. Karenanya OOP mengelola kompleksitas pada level rendah (pengkodean) sementara metodologi ini seperti Pola dan Prinsip Desain memandu desain solusi pada level (sistem dan aplikasi) yang lebih tinggi dan membuat pengembangan perangkat lunak dan penanganan kompleksitas lebih mudah dikelola.
Untuk menjawab pertanyaan Anda, ya, OOP hanyalah solusi untuk menangani kompleksitas di antara banyak solusi lainnya. Ini adalah solusi pada level rendah. Kita membutuhkan Pola dan Prinsip Desain untuk memandu OOP di tingkat yang lebih tinggi.
Pemrograman berorientasi objek mengelola kompleksitas esensial dan opsional, tetapi tidak mengurangi keduanya.
Saya lebih suka definisi yang diberikan oleh Eric Steven Raymond dalam The Art of Unix Programming , karena ia menggambarkan antara kompleksitas esensial, opsional, dan tidak disengaja. http://www.faqs.org/docs/artu/ch13s01.html#id2964646
OOP tidak melakukan apa pun untuk kompleksitas esensial atau opsional, mereka adalah fungsi dari persyaratan program. Ini dapat memiliki efek pada kompleksitas yang tidak disengaja, di mana Anda dapat membuat desain yang lebih elegan terkadang dengan OOP. Namun terkadang, desainnya lebih buruk saat menggunakan OOP.
Masalah kompleks tidak dapat dibuat lebih sederhana melalui teknologi, mereka hanya dapat dikelola melalui teknologi.
OOP adalah teknologi, konsep, dan cara untuk mendekati masalah.
OOP memberi Anda alat untuk menegakkan desain yang dapat membuatnya lebih mudah untuk mengelola kompleksitas, tetapi Anda dapat dengan mudah memiliki desain yang buruk yang meningkatkan kompleksitas Anda. Dengan kata lain, jika tidak digunakan dengan benar, Anda dapat memiliki kompleksitas yang disebabkan teknologi dalam masalah Anda.
Ingatlah bahwa ada banyak aspek lain yang akan menentukan seberapa sukses proyek Anda nantinya (yaitu gaya manajemen proyek, definisi masalah, manajemen perubahan, dll ...). Teknologi yang Anda gunakan hanya relevan dalam berapa banyak akan membantu Anda mengelola masalah.
Pada akhirnya, pemrograman berorientasi objek tidak bisa menjadi solusi untuk kompleksitas; itu hanya alat untuk mengelolanya. (jika digunakan dengan benar)
Orientasi Objek (seperti yang digunakan secara konvensional) adalah alat yang berguna dalam banyak keadaan, tetapi itu bukan solusi yang cukup untuk kompleksitas.
Secara khusus, sering menambah banyak " kompleksitas insidental ". Contohnya adalah kompleksitas seputar warisan implementasi, kebutuhan untuk menyediakan banyak "fungsi standar" suach sama dengan () dan kode hash () dll. Presentasi yang bagus oleh Stuart Halloway pada topik ini: " Kesederhanaan Tidak Mudah "
Objek dalam kebanyakan bahasa juga cenderung merangkum banyak keadaan yang bisa berubah - yang dalam dunia bersamaan semakin mulai terlihat seperti keputusan desain yang buruk. Lagi-lagi sebuah video yang menarik oleh Rich Hickey melihat perbedaan antara identitas objek dan negara, dan bagaimana mungkin kesalahan untuk mengacaukan keduanya.
Pemrograman berorientasi objek adalah cara untuk merepresentasikan masalah, tidak lebih, tidak kurang. Ini, dalam dan dari dirinya sendiri, tidak ada yang kurang kompleks daripada paradigma pemrograman lainnya. Sistem OOP yang dirancang dengan baik mengelola dan mengurangi kompleksitas, tetapi juga sangat mudah untuk merancang sistem yang jauh lebih kompleks daripada yang diperlukan dan menghalangi segalanya.
Seperti yang sering dikatakan tentang C ++, OOP memberi Anda cukup tali untuk menggantung diri.
Saya pikir YA , hanya karena memungkinkan Anda untuk mengiris kompleksitas menjadi "blok bangunan" mandiri kecil yang menyembunyikan detail, dan kemudian menggunakannya untuk membuat fungsionalitas yang Anda butuhkan, selangkah demi selangkah, lapis demi lapis.
Memecah dan menaklukkan.
OOP adalah upaya solusi.
Cara terbaik untuk mengelola kompleksitas adalah dengan membuat abstraksi. Jika saya dapat mengubah data saya menjadi koleksi yang bermanfaat, dengan fungsi yang dapat dikenali yang beroperasi pada koleksi tersebut, saya dapat mulai berpikir tentang koleksi tersebut sebagai "hal" yang berbeda. Itulah dasar untuk kelas dan metode. Dalam hal itu, OOP yang dirancang dengan baik dapat membantu mengelola kompleksitas.
Di suatu tempat di sepanjang jalan, seseorang memutuskan bahwa kami dapat menggunakan OOP untuk membantu memecahkan masalah penggunaan kembali kode. Maksudku, mengapa menciptakan kembali kemudi? Jika orang lain telah melakukan banyak upaya untuk menyelesaikan masalah ini, manfaatkan apa yang telah mereka lakukan, tambahkan tweak yang diperlukan, proyek khusus Anda, dan voila! Anda telah membuat aplikasi yang kuat dan canggih dengan pekerjaan yang relatif sedikit. Pemrogram OO bisa menjadi pemrogram yang sangat produktif.
Hasil akhirnya adalah bahwa pemrogram OO modern akhirnya menjadi "magang tukang sihir," di mana mereka mengikat banyak perpustakaan besar, berat dengan beberapa baris "lem" dan mendapatkan sesuatu yang berfungsi. Agak. Agak. Sebagian besar waktu. Apakah ada efek samping potensial dari penggunaan perpustakaan ini dengan yang itu? Mungkin. Tapi siapa yang punya waktu untuk benar-benar menggali kode yang ada di perpustakaan itu? Terutama ketika perpustakaan berkembang. Hasilnya adalah kita berakhir dengan aplikasi kembung, di mana seorang programmer membutuhkan beberapa kelas dan metode dari perpustakaan itu, tetapi aplikasi tersebut harus menanggung semua hal-hal LAIN yang tidak mereka butuhkan.
Hasil akhirnya adalah bahwa Anda berakhir dengan kompleksitas yang jauh lebih banyak daripada yang Anda butuhkan.
Mekanisme lain untuk menangani kompleksitas yang ingin Anda pisahkan fungsinya. Anda ingin semua fungsi akses data Anda di satu tempat. Anda ingin semua fungsi antarmuka pengguna Anda di satu tempat. Anda ingin semua pengontrol di satu tempat. Jadi, Anda membuat kelas yang berbeda yang mengelola berbagai bagian fungsi. Sejauh ini baik. Dan ini berskala, sampai taraf tertentu; pengembang Anda yang terampil dengan akses data dapat menulis kelas-kelas itu, orang-orang antarmuka pengguna Anda dapat menulis kelas-antarmuka pengguna, dll. Semua baik dan baik.
Sampai Anda harus mempertahankan sesuatu yang ditulis oleh orang lain.
Ya, ada baiknya mengetahui bahwa semua fungsi akses data berada di sini. Tapi apa yang memanggil mereka?
Metode ini memanggil metode itu di kelas itu. Tetapi ketika saya melihat definisi kelas, tidak ada metode dengan nama itu. Oh, itu diwarisi dari sesuatu yang lain satu atau dua lapisan di rantai pewarisan. Tunggu sebentar; kelas yang mengimplementasikan antarmuka? Berapa banyak kelas yang mengimplementasikan antarmuka itu? Dan kami menggunakan beberapa sistem run-time yang rumit (saya sedang melihat Anda, Spring) untuk "menyatukan" contoh-contoh kelas pada saat run-time? Di mana setiap kelas yang mengimplementasikan antarmuka itu dapat digunakan?
Anda berakhir dengan banyak metode kecil dan terpisah yang melakukan hal-hal yang tepat. Tapi yang ini memanggil yang satu itu, di kelas lain. Yang memanggil satu itu, di kelas lain. Yang memanggil satu itu, masih kelas lain. Yang memanggil yang itu, di kelas tambahan. Yang mengembalikan hasil dari tipe tertentu. Di mana Anda harus memanggil metode untuk melakukan hal tertentu. Yang mengembalikan hasil dari tipe lain. Dll
Ada istilah untuk ini: kode spageti.
Anda berakhir dengan sistem yang sangat kompleks yang diperlukan hanya untuk menyusun kode. Karenanya IDE seperti Visual Studio, Eclipse dan NetBeans. Kesemuanya memiliki kurva belajar yang signifikan. Memang, banyak dari mereka mampu merangkum / menggabungkan beberapa alat, yang dikembangkan oleh kelompok yang berbeda, yang masing-masing memiliki kurva belajar sendiri.
Ini mengelola kompleksitas?
Kode debug dua kali lebih sulit daripada menulisnya. Semoga berhasil men-debug beberapa hal ini. Terutama jika menggunakan beberapa pustaka, "kabel bersama" pada saat run-time menggunakan semacam sistem ketergantungan-injeksi.
Singkatnya: OOP menyediakan apa yang tampak seperti alat yang menjanjikan untuk membantu mengelola kompleksitas. Kenyataannya adalah kode yang dihasilkan cenderung membengkak mengerikan (karena Anda tidak dapat mengekstrak hanya bagian-bagian yang Anda butuhkan dari semua pustaka yang ditautkan) dan Anda memerlukan alat canggih hanya untuk menavigasi kode. Dengan cepat menjadi mimpi buruk pemeliharaan.
IMHO, ini rugi bersih; itu menambah lebih banyak kompleksitas daripada yang dihilangkan. Itu memungkinkan Anda untuk melakukan hal-hal yang akan sangat sulit, bahkan mungkin mustahil, tanpanya. Tetapi setiap proyek besar dengan cepat berkembang menjadi kekacauan yang tidak dapat dipelihara.
Jika Anda sudah tahu cara kerjanya, dan Anda dapat mengingatnya, Anda mungkin memiliki kesempatan untuk mempertahankannya.
Ingatlah untuk menerapkan Hukum Eagleson: kode apa pun milik Anda, yang belum Anda lihat dalam enam bulan, mungkin juga ditulis oleh orang lain.
Pada tingkat tertentu ...
Mengapa? Karena itu memfasilitasi modularitas yang sangat logis. Setidaknya dibandingkan dengan pemrograman prosedural di mana terlalu menggoda untuk hanya menulis tumpukan besar kode spaghetti.
Alasan pemrograman berorientasi objek tampaknya membantu kita menangani kerumitan adalah karena memaksa kita untuk menulis kode dengan cara tertentu, bukan berbagai macam cara. Pemrograman berorientasi tugas jauh lebih intuitif, itulah sebabnya pemrograman dimulai dengan cara itu. Orientasi objek membutuhkan pelatihan dan latihan untuk memahami dan menggunakan secara efektif, tetapi dengan membatasi pemrograman ke jalur tertentu, itu memungkinkan mereka yang terlatih untuk secara efektif menjaga kode yang ditulis.
Ini tidak lebih logis atau dunia nyata daripada metode lain, itu hanya cara memfokuskan penyelesaian masalah kami melalui lensa yang sama. Banyak spesialisasi teknis menggunakan paradigma metodologi kaku non-intuitif untuk menangani kompleksitas tugas mereka.
Metode ketiga untuk menangani kompleksitas adalah pemrograman fungsional, dan mungkin akan ada metode baru lainnya di masa depan.
saya pikir ini lebih merupakan solusi untuk pemeliharaan, karena, sebagai seorang programmer, Anda seharusnya meletakkan metode di mana Anda memiliki data, sehingga menciptakan model objek dari aplikasi Anda.
ya, ini juga merupakan solusi untuk kompleksitas dengan menyediakan model bagi Anda untuk "melihat" kode Anda secara alami, sebagai objek yang memiliki properti dan tindakan yang mungkin