Catatan : pertanyaan ini adalah kutipan yang diedit dari posting blog yang saya tulis beberapa bulan yang lalu. Setelah menempatkan tautan ke blog dalam komentar di Programmers.SE seseorang meminta saya mengirim pertanyaan di sini sehingga mereka dapat menjawabnya. Postingan ini saya yang paling populer, sebagai orang tampaknya untuk mengetik "Aku tidak mengerti pemrograman berorientasi" ke dalam Google banyak . Jangan ragu untuk menjawab di sini, atau dalam komentar di Wordpress.
Apa itu pemrograman berorientasi objek? Tidak ada yang memberi saya jawaban yang memuaskan. Saya merasa seperti Anda tidak akan mendapatkan definisi yang baik dari seseorang yang berkeliling mengatakan "objek" dan "berorientasi objek" dengan hidungnya di udara. Anda juga tidak akan mendapatkan definisi yang baik dari seseorang yang tidak melakukan apa pun selain pemrograman berorientasi objek. Tidak ada orang yang mengerti pemrograman prosedural dan berorientasi objek yang pernah memberi saya ide yang konsisten tentang apa yang sebenarnya program berorientasi objek lakukan.
Dapatkah seseorang tolong beri saya ide-ide mereka tentang manfaat pemrograman berorientasi objek?
sumber
Jawaban:
Pikirkan perangkat lunak sebagai mesin atau jalur perakitan yang ada di dalam komputer. Beberapa bahan baku dan komponen dimasukkan ke dalam mesin, dan mengikuti serangkaian prosedur untuk memprosesnya menjadi beberapa produk akhir. Prosedur diatur untuk melakukan operasi tertentu pada beberapa bahan mentah atau komponen ke serangkaian parameter tertentu (misalnya, waktu, suhu, jarak, dll) dalam urutan tertentu. Jika detail operasi yang akan dilakukan salah, atau sensor mesin tidak dikalibrasi dengan benar, atau jika beberapa bahan baku atau komponen tidak sesuai dengan standar kualitas yang diharapkan, itu dapat mengubah hasil operasi dan produk tidak akan berubah seperti yang diharapkan.
Mesin seperti itu sangat kaku dalam operasinya dan input yang dapat diterima. Mesin tidak mempertanyakan kecerdasan desainer atau lingkungan operasinya saat ini. Itu akan terus mengikuti prosedur selama itu diarahkan. Bahkan jika perubahan bahan baku atau komponen dapat memiliki efek dramatis pada apa yang terjadi pada operasi selanjutnya, mesin tetap akan melakukan prosedurnya. Proses ini perlu ditinjau untuk melihat perubahan apa pada prosedur yang diperlukan untuk mengkompensasi dan menghasilkan hasil yang diinginkan. Perubahan pada desain atau konfigurasi produk mungkin juga memerlukan perubahan signifikan pada operasi yang dilakukan atau pesanan mereka. Meskipun mereka yang bertanggung jawab atas produksi dengan cepat mempelajari pentingnya mengisolasi operasi sebanyak mungkin untuk mengurangi efek yang tidak diinginkan di antara mereka, banyak asumsi dibuat dari komponen kondisi saat mereka menjalani pemrosesan; asumsi yang mungkin tidak terdeteksi hingga produk akhir ada di tangan pengguna di beberapa lingkungan operasi yang berbeda.
Seperti itulah pemrograman prosedural itu.
Apa yang diberikan orientasi objek adalah cara untuk menghilangkan asumsi kondisi komponen; dengan demikian, operasi yang akan dilakukan pada komponen itu dan bagaimana mengintegrasikannya ke dalam produk akhir. Dengan kata lain, OOP seperti mengambil detail proses untuk berurusan dengan beberapa komponen tertentu dan memberikannya kepada mesin yang lebih kecil untuk melakukannya. Mesin yang lebih besar yang bertanggung jawab untuk proses ini memberi tahu mesin khusus komponen yang operasi yang diharapkan akan dilakukan tetapi meninggalkan rincian langkah-langkah yang harus ditangani oleh mesin khusus komponen.
Adapun keuntungan dari orientasi objek daripada perangkat lunak yang tidak berorientasi objek:
sumber
Dari blog Anda, tampaknya Anda terbiasa dengan pemrograman imperatif dan fungsional, dan bahwa Anda terbiasa dengan konsep dasar yang terlibat dalam pemrograman berorientasi objek, tetapi Anda tidak pernah benar-benar memilikinya "klik" untuk apa membuatnya bermanfaat. Saya akan mencoba menjelaskan dalam hal pengetahuan itu, dan berharap itu membantu Anda.
Pada intinya, OOP adalah cara untuk menggunakan paradigma imperatif untuk mengelola kompleksitas tingkat tinggi dengan lebih baik dengan menciptakan struktur data "pintar" yang memodelkan domain masalah. Dalam program (berorientasi prosedural non-objek) standar, Anda punya dua hal dasar: variabel, dan kode yang tahu apa yang harus dilakukan dengan mereka. Kode mengambil input dari pengguna dan berbagai sumber lain, menyimpannya dalam variabel, beroperasi di atasnya, dan menghasilkan data keluaran yang masuk ke pengguna atau berbagai lokasi lainnya.
Pemrograman berorientasi objek adalah cara untuk menyederhanakan program Anda dengan mengambil pola dasar itu dan mengulanginya dalam skala yang lebih kecil. Sama seperti sebuah program adalah kumpulan besar data dengan kode yang tahu apa yang harus dilakukan dengannya, setiap objek adalah sepotong kecil data yang terikat pada kode yang tahu apa yang harus dilakukan dengannya.
Dengan memecah domain masalah menjadi potongan-potongan kecil dan memastikan sebanyak mungkin data terikat langsung ke kode yang tahu apa yang harus dilakukan dengan itu, Anda membuatnya lebih mudah untuk alasan tentang proses secara keseluruhan dan juga tentang sub- masalah yang membentuk proses.
Dengan mengelompokkan data ke dalam kelas objek, Anda dapat memusatkan kode yang terkait dengan data itu, membuat kode yang relevan lebih mudah ditemukan dan di-debug. Dan dengan merangkum data di belakang penentu akses dan hanya mengaksesnya melalui metode, (atau properti, jika bahasa Anda mendukungnya), Anda sangat mengurangi potensi korupsi data atau pelanggaran invarian.
Dan dengan menggunakan warisan dan polimorfisme, Anda dapat menggunakan kembali kelas yang sudah ada, menyesuaikannya agar sesuai dengan kebutuhan spesifik Anda, tanpa harus memodifikasi yang asli atau menulis ulang semuanya dari bawah ke atas. (Itu adalah hal yang tidak boleh kamu lakukan , jika kamu bisa menghindarinya.) Berhati-hatilah kamu mengerti objek dasar kamu, atau kamu bisa berakhir dengan kanguru pembunuh .
Bagi saya, ini adalah prinsip dasar pemrograman berorientasi objek: manajemen kompleksitas, pemusatan kode dan pemodelan masalah-domain yang ditingkatkan melalui penciptaan kelas objek, pewarisan dan polimorfisme, dan peningkatan keamanan tanpa mengorbankan kekuatan atau kontrol melalui penggunaan enkapsulasi dan properti. Saya harap ini membantu Anda memahami mengapa begitu banyak programmer menganggapnya berguna.
EDIT: Menanggapi pertanyaan Joel di komentar,
Penafian kecil di sini. Model "program berorientasi objek" saya pada dasarnya adalah model Delphi, yang sangat mirip dengan model C # /. NET karena dibuat oleh mantan anggota tim Delphi. Apa yang saya katakan di sini mungkin tidak berlaku, atau tidak berlaku banyak, dalam bahasa OO lainnya.
Program berorientasi objek adalah program di mana semua logika disusun di sekitar objek. Tentu saja ini harus di-boot di suatu tempat. Program Delphi khas Anda berisi kode inisialisasi yang membuat objek singleton yang disebut
Application
. Pada awal program, ia memanggilApplication.Initialize
, lalu panggilan keApplication.CreateForm
untuk setiap bentuk yang ingin Anda muat ke dalam memori dari awal, dan kemudianApplication.Run,
yang menampilkan formulir utama di layar dan memulai input / event loop yang membentuk inti dari setiap program komputer interaktif.Aplikasi dan polling formulir Anda untuk acara yang masuk dari OS dan menerjemahkannya menjadi panggilan metode pada objek Anda. Satu hal yang sangat umum adalah penggunaan event handler, atau "delegate" di .NET-speak. Objek memiliki metode yang mengatakan, "lakukan X dan Y, tetapi juga periksa untuk melihat apakah event handler khusus ini ditugaskan, dan panggil jika ada." Event handler adalah penunjuk metode - penutupan yang sangat sederhana yang berisi referensi ke metode dan referensi ke instance objek - yang digunakan untuk memperluas perilaku objek. Misalnya, jika saya memiliki objek tombol pada formulir saya, saya menyesuaikan perilakunya dengan melampirkan pengendali event OnClick, yang menyebabkan beberapa objek lain mengeksekusi metode ketika tombol diklik.
Jadi dalam program berorientasi objek, sebagian besar pekerjaan dilakukan dengan mendefinisikan objek dengan tanggung jawab tertentu dan menghubungkannya bersama-sama, baik melalui pointer metode atau dengan satu objek secara langsung memanggil metode yang didefinisikan dalam antarmuka publik objek lain. (Dan sekarang kita kembali ke enkapsulasi.) Ini adalah gagasan bahwa saya tidak memiliki konsep kembali sebelum saya mengambil kelas OOP di perguruan tinggi.
sumber
Saya pikir OOP pada dasarnya hanya nama yang diberikan untuk sesuatu yang Anda mungkin tergoda untuk melakukannya, seperti saya.
Kembali ketika saya masih seorang programmer bayi, bahkan di Fortran, ada yang namanya pointer ke subrutin. Sangat berguna untuk dapat melewatkan pointer ke subrutin sebagai argumen ke subrutin lainnya.
Maka hal berikutnya yang akan sangat berguna adalah menyimpan pointer ke subrutin di dalam catatan struktur data. Dengan begitu, Anda bisa mengatakan catatan "tahu" bagaimana melakukan operasi itu sendiri.
Saya tidak yakin apakah mereka pernah membangunnya menjadi Fortran, tetapi mudah dilakukan di C dan keturunannya.
Jadi di bawahnya, itu adalah ide yang sederhana dan berguna yang mungkin membuat Anda tergoda untuk melakukannya sendiri, dan lebih mudah dilakukan dalam bahasa yang lebih baru, bahkan jika beberapa orang mengubahnya menjadi kereta musik raksasa yang penuh dengan kata-kata yang menakutkan.
sumber
Ada berbagai macam sistem OO, dan sulit untuk mendapatkan definisi yang disetujui semua orang. Daripada mencoba menunjukkan bagaimana OO Java mirip dengan Common Lisp Object System, saya akan mulai dengan sesuatu yang lebih konvensional, langkah demi langkah.
Misalkan Anda memiliki banyak objek yang ada sebagai data yang tersebar. Poin, misalnya, mungkin elemen dalam array X, Y, dan Z. Untuk mempertimbangkan titik itu sendiri, masuk akal untuk menarik semua data bersama-sama ke dalam sesuatu seperti C
struct
.Sekarang, untuk objek data apa pun, kami mengumpulkan semua data. Namun, dalam program prosedural, kode tersebut tersebar. Misalkan kita berurusan dengan bentuk geometris. Ada fungsi besar untuk menggambar bentuk, dan perlu tahu tentang semua bentuk. Ada fungsi besar untuk menemukan area, dan lainnya untuk perimeter. Kode untuk lingkaran tersebar melalui beberapa fungsi, dan untuk menambahkan tipe bentuk lain kita perlu tahu fungsi mana yang harus diubah. Dalam sistem berorientasi objek, kami mengumpulkan fungsi ke dalam hal yang sama (
class
) sebagai data. Oleh karena itu, jika kita ingin melihat semua kode lingkaran, itu ada dalamCircle
definisi, dan jika kita ingin menambahkanQuartercircle
kita cukup menulis kelasnya dan kita punya kodenya.Satu sisi manfaat dari ini adalah bahwa kita dapat mempertahankan invarian kelas, hal-hal yang benar tentang setiap anggota kelas. Dengan membatasi kode di luar kelas agar tidak langsung mengacaukan anggota data kelas, kami memiliki semua kode yang dapat mengubah data kelas di satu tempat, dan kami dapat mengonfirmasi bahwa itu tidak melakukan apa pun yang kacau (seperti memiliki segitiga dengan satu kaki) lebih lama dari dua lainnya digabungkan). Ini berarti kita dapat mengandalkan beberapa properti dari setiap anggota kelas, dan tidak perlu memeriksa untuk melihat apakah suatu objek waras setiap kali kita menggunakannya.
Manfaat utama datang dengan warisan dan polimorfisme. Dengan mendefinisikan semua berbagai bentuk ini sebagai subclass dari sebuah kelas yang dipanggil
Shape
, kita dapat membuat kode kita memanipulasiShape
s, dan tugas subobyek bentuk adalah untuk melakukan apa pun yang dipanggil oleh manipulasi. Ini berarti kita tidak perlu menyentuh kode lama yang diuji ketika kita menambahkan bentuk baru atau memperbaiki perilaku yang lama. Kami secara otomatis memiliki kode lama yang dapat langsung memanfaatkan kode baru. Alih-alih membuat kode pengendali menyadari semua bentuk yang berbeda, dan harus mempertahankan fungsi yang menyadari semua bentuk yang berbeda, kami hanya berurusan dengan bentuk dan propertinya, sambil mempertahankanShape
subkelas. Ini menyederhanakan kode pengendali.Kami memiliki beberapa keunggulan di sini. Karena kita memiliki invarian kelas, kita dapat berargumen tentang objek data yang lebih besar dengan cara yang sama kita berargumen tentang tipe bawaan, artinya kita sering dapat membagi konsep kompleks menjadi yang lebih sederhana. Karena sebagian besar kode lingkaran terkandung
Circle
, kami telah meningkatkan lokalitas. Karena tidak ada konsep lingkaran yang tersebar melalui beberapa fungsi yang berbeda di tempat yang berbeda, kami mendapatkan lebih sedikit sambungan di antara rutinitas, dan tidak perlu khawatir tentang menjaga mereka tetap sinkron. Karena kelas, pada dasarnya, tipe, kita dapat mengambil keuntungan dari sistem tipe yang ada untuk menangkap penggunaan kelas yang tidak kompatibel.sumber
OO memiliki banyak definisi berbeda, ya. Saya yakin Anda dapat menemukan ini sendiri. Saya pribadi menyukai Rees Re: OO sebagai cara untuk memahami mereka. Saya kira Anda sudah membaca itu sejak Anda mengutip Paul Graham. (Saya merekomendasikannya kepada siapa pun yang tertarik pada OO.) Saya akan sedikit banyak mengadopsi definisi Java di sini {1,2,3,7,8,9}.
Pertanyaan tentang kegunaan OO, terutama cara saya mendekatinya, layak mendapatkan jawaban yang jauh lebih besar dengan beberapa ribu baris kode (sebagian agar tidak hanya menjadi sekumpulan pernyataan). Namun, inilah ringkasan dari dokumen hipotetis itu.
Saya tidak berpikir OO sangat berguna dalam skala kecil, katakanlah, sekitar beberapa ratus baris. Secara khusus, bahasa OO tanpa pengaruh fungsional yang baik cenderung membuatnya sangat menyakitkan untuk menyelesaikan hal-hal sederhana dengan segala jenis koleksi atau apa pun yang membutuhkan banyak tipe data. Di sinilah sebagian besar pola desain berperan; mereka band-aids pada kekuatan rendah dari bahasa yang mendasarinya .
Pada sekitar seribu baris, mulai lebih sulit untuk melacak semua operasi dan struktur data dan bagaimana mereka berhubungan. Ini membantu, pada titik ini, untuk memiliki cara untuk secara eksplisit mengatur struktur data dan operasi, untuk menggambar batas-batas modul dan mendefinisikan tanggung jawab, dan untuk memiliki cara yang mudah untuk memahami definisi tersebut ketika Anda mencoba untuk memprogramnya.
Java-ish OO adalah solusi setengah jalan untuk masalah-masalah ini yang kebetulan telah memenangkan kontes popularitas. Karena ini adalah mekanisme yang sama yang diterapkan orang Jawa pada masalah skala kecil yang diciptakan oleh bahasa yang kurang bertenaga, ia cenderung mulai terlihat lebih seperti solusi ajaib untuk segalanya daripada hanya cara untuk tetap teratur. Orang yang akrab dengan pemrograman fungsional cenderung lebih suka solusi lain, seperti CLOS atau kelas tipe Haskell, atau template metaprogramming ketika terjebak dalam C ++, atau yang lain (seperti saya, bekerja setiap hari di C #) menggunakan OO tetapi hanya tidak terlalu bersemangat tentang hal itu .
sumber
OOP berupaya memodelkan konsep dunia nyata dalam hal objek dan interaksi di antara mereka. Sebagai manusia, kita cenderung memproses dunia dari segi objek. Dunia ini penuh dengan objek yang memiliki properti tertentu dan dapat melakukan hal-hal seperti berinteraksi dengan objek lain. OOP memungkinkan model dunia dengan istilah serupa. Sebagai contoh,
Tetapi sebuah mobil tidak dapat bergerak sendiri, ia membutuhkan seseorang untuk mengendarainya - interaksi antara Objek.
sumber
OOP = struktur data + pesan yang lewat + warisan, yang semuanya adalah evolusi logis dalam model pemrograman.
OOP dapat dipahami (oleh programmer) dalam waktu sekitar 90 detik (lihat profil saya untuk tautan). Konsepnya sangat sederhana.
Cara menerapkannya adalah masalah lain. Hanya karena Anda tahu cara mengayunkan palu tidak berarti Anda tahu cara mendesain dan membangun rumah. ;-)
sumber
Saya menulis posting blog beberapa waktu lalu yang mungkin Anda temukan membantu: Dijelaskan prosedural vs. OOP .
sumber
Cara pertama saya memahaminya adalah:
Sebelum pemrograman berorientasi objek, Anda memiliki pemrograman terstruktur . Semuanya berpusat di sekitar proses. Pertanyaan pertama yang harus Anda tanyakan pada diri sendiri adalah " Apa yang ingin saya lakukan dengan informasi itu? ".
Dengan pemrograman berorientasi objek, itu berpusat di sekitar data. Pertanyaan pertama yang harus Anda tanyakan pada diri sendiri adalah " Informasi penyihir yang perlu saya tangani? ". Ini membuat abstraksi lebih mudah.
sumber
Karena Anda memahami struct, dan Anda memahami pointer fungsi, dan Anda memahami struct dengan pointer fungsi, dari perspektif Anda, saya akan mendefinisikan pemrograman berorientasi objek hanya sebagai "pemrograman, dengan banyak penggunaan struct yang memiliki pointer fungsi". Itu masih pemrograman dalam pengertian tradisional - itu semua data, dan kode yang bertindak atas data. Perbedaannya hanyalah bagaimana semua informasi itu didefinisikan dan bagaimana Anda mendekati mendefinisikannya.
Mungkin penyederhanaan berlebihan adalah bahwa pemrograman tradisional adalah "kode, dengan beberapa struktur data", dan pemrograman berorientasi objek adalah "struktur data, dengan beberapa kode". Keduanya masih memiliki struktur data, dan keduanya masih memiliki kode. Pemrograman berorientasi objek, kemudian, tidak lebih dari tindakan mendefinisikan jenis data di muka, dan menegakkan kontrak untuk bagaimana mereka berkomunikasi melalui serangkaian fungsi.
Seperti yang telah Anda amati, ada sejumlah besar aplikasi yang ini bukan cara yang bagus untuk mengimplementasikan solusi. Anda tampaknya hidup di dunia yang sebagian besar terdiri dari aplikasi semacam itu. Dalam posting blog Anda, Anda menyebutkan melihat implementasi dari masalah "99 botol bir" ("showcase pemrograman favorit Anda"). 99 botol bir tentu merupakan bagian dari kategori itu. Mencoba memahami pemrograman berorientasi objek dengan melihat implementasi dari 99 botol bir adalah seperti mencoba memahami arsitektur bangunan tinggi dengan melihat rumah pohon. Bahkan rumah pohon yang dibangun dengan sangat baik hanya bisa mengajarimu begitu banyak.
TL; DR: Pemrograman OO seperti pemrograman tradisional, kecuali Anda lebih memfokuskan upaya Anda dalam mendefinisikan struktur data di muka, dan Anda memiliki struktur data yang berkomunikasi satu sama lain melalui pointer fungsi.
sumber
Saya pikir halaman Wikipedia adalah tempat yang bagus untuk mendapatkan dasar-dasarnya:
http://en.wikipedia.org/wiki/Object-oriented_programming
Pada dasarnya idenya adalah pemrograman prosedural, yang OOP coba tingkatkan, fokus pada proses yang dimodelkan. OOP bergeser ke model di mana fokusnya adalah pada "hal-hal" yang Anda modelkan, dan proses serta data dari hal-hal itu terkandung dalam hal-hal itu.
Jadi, sebagai contoh, katakanlah Anda sedang merancang aplikasi untuk melacak daftar tugas. Dalam pemrograman prosedural, entitas tingkat atas Anda dalam model akan menjadi proses yang terjadi, seperti membuat tugas, menghapus tugas, mengubah info tugas, dll. Dalam model OOP, Anda akan lebih fokus membuat Tugas, dan pikirkan data dan proses apa yang menjadi tanggung jawab Task. Dan kemudian fokus pada objek lain yang berinteraksi dengan Tugas, seperti mungkin Catatan atau sesuatu jika Anda ingin menyimpan catatan tentang Tugas.
Saya harap itu membantu. Teruslah membaca tentang hal itu dan melihat kode dan tiba-tiba akan "klik". Itulah pengalaman saya.
sumber