Pemrograman Berorientasi Aspek vs. Pemrograman Berorientasi Objek

199

Seperti kebanyakan pengembang di sini dan di seluruh dunia, saya telah mengembangkan sistem perangkat lunak menggunakan teknik pemrograman berorientasi objek (OOP) selama bertahun-tahun. Jadi ketika saya membaca bahwa pemrograman berorientasi aspek (AOP) membahas banyak masalah yang OOP tradisional tidak menyelesaikan sepenuhnya atau langsung, saya berhenti sejenak dan berpikir, apakah itu nyata?

Saya telah membaca banyak informasi yang mencoba mempelajari kunci-kunci paradigma AOP ini dan saya berada di tempat yang sama, jadi, saya ingin lebih memahami manfaatnya dalam pengembangan aplikasi dunia nyata.

Apakah ada yang punya jawabannya?

yeradis
sumber
7
Semua jawaban sudah sangat bagus, ini adalah kasus yang sempurna untuk satu jawaban yang diedit komunitas yang akan menggabungkan semuanya. Semua mengatakan hal yang sama tetapi dengan cara yang berbeda dan menggunakan contoh berbeda yang menambah nilai keseluruhan
Vinko Vrsalovic

Jawaban:

323

Kenapa "vs"? Itu bukan "vs". Anda dapat menggunakan pemrograman Berorientasi Aspek dalam kombinasi dengan pemrograman fungsional, tetapi juga dalam kombinasi dengan yang Berorientasi Objek. Ini bukan "vs", itu adalah "Pemrograman Berorientasi Aspek dengan Pemrograman Berorientasi Objek".

Bagi saya AOP adalah semacam "meta-programming". Segala sesuatu yang dilakukan AOP juga dapat dilakukan tanpanya dengan hanya menambahkan lebih banyak kode. AOP hanya menghemat Anda menulis kode ini.

Wikipedia memiliki salah satu contoh terbaik untuk pemrograman meta ini. Asumsikan Anda memiliki kelas grafis dengan banyak metode "set ... ()". Setelah setiap metode yang ditetapkan, data gambar berubah, dengan demikian gambar berubah dan dengan demikian gambar perlu diperbarui di layar. Asumsikan untuk mengecat ulang gambar yang harus Anda panggil "Display.update ()". Pendekatan klasik adalah untuk menyelesaikan ini dengan menambahkan lebih banyak kode . Di akhir setiap set metode yang Anda tulis

void set...(...) {
    :
    :
    Display.update();
}

Jika Anda memiliki 3 set-metode, itu bukan masalah. Jika Anda memiliki 200 (hipotetis), semakin menyakitkan untuk menambahkan ini di mana-mana. Juga setiap kali Anda menambahkan metode-set baru, Anda harus yakin untuk tidak lupa menambahkan ini ke akhir, jika tidak, Anda baru saja membuat bug.

AOP memecahkan ini tanpa menambahkan banyak kode, alih-alih Anda menambahkan aspek:

after() : set() {
   Display.update();
}

Dan itu dia! Alih-alih menulis sendiri kode pembaruan, Anda hanya memberi tahu sistem bahwa setelah set point () dicapai, ia harus menjalankan kode ini dan akan menjalankan kode ini. Tidak perlu memperbarui 200 metode, tidak perlu memastikan Anda tidak lupa menambahkan kode ini pada set-metode baru. Selain itu, Anda hanya perlu titik potong:

pointcut set() : execution(* set*(*) ) && this(MyGraphicsClass) && within(com.company.*);

Apa artinya? Itu berarti jika suatu metode bernama "set *" (* berarti nama apa pun dapat mengikuti setelah set), terlepas dari apa metode kembali (tanda bintang pertama) atau parameter apa yang diperlukan (tanda bintang ketiga) dan itu adalah metode MyGraphicsClass dan ini kelas adalah bagian dari paket "com.company. *", maka ini adalah set () pointcut. Dan kode pertama kami mengatakan " setelah menjalankan metode apa pun yang merupakan set pointcut, jalankan kode berikut".

Lihat bagaimana AOP secara elegan menyelesaikan masalah di sini? Sebenarnya semua yang dijelaskan di sini dapat dilakukan pada waktu kompilasi. Seorang preprocessor AOP hanya dapat memodifikasi sumber Anda (misalnya menambahkan Display.update () ke akhir setiap metode set-pointcut) sebelum bahkan mengkompilasi kelas itu sendiri.

Namun, contoh ini juga menunjukkan salah satu kelemahan besar dari AOP. AOP sebenarnya melakukan sesuatu yang oleh banyak programmer dianggap sebagai " Anti-Pola ". Pola yang tepat disebut " Aksi di kejauhan ".

Tindakan di kejauhan adalah anti-pola (kesalahan umum yang diakui) di mana perilaku di satu bagian program bervariasi berdasarkan sulit atau tidak mungkin untuk mengidentifikasi operasi di bagian lain dari program.

Sebagai pemula untuk suatu proyek, saya mungkin hanya membaca kode dari setiap metode-set dan menganggapnya rusak, karena tampaknya tidak memperbarui tampilan. Saya tidak melihat dengan hanya melihat kode dari set-method, bahwa setelah dieksekusi, beberapa kode lain akan "secara ajaib" dijalankan untuk memperbarui tampilan. Saya menganggap ini kerugian serius! Dengan membuat perubahan pada metode, bug aneh mungkin diperkenalkan. Lebih jauh memahami aliran kode di mana hal-hal tertentu tampaknya berfungsi dengan benar, tetapi tidak jelas (seperti yang saya katakan, mereka hanya bekerja secara ajaib ... entah bagaimana), sangat sulit.

Memperbarui

Hanya untuk mengklarifikasi bahwa: Beberapa orang mungkin memiliki kesan saya katakan AOP adalah sesuatu yang buruk dan tidak boleh digunakan. Bukan itu yang saya katakan! AOP sebenarnya adalah fitur yang hebat. Saya hanya mengatakan "Gunakan dengan hati-hati". AOP hanya akan menimbulkan masalah jika Anda mencampur kode normal dan AOP untuk Aspek yang sama . Pada contoh di atas, kita memiliki Aspek memperbarui nilai-nilai objek grafis dan mengecat objek yang diperbarui. Itu sebenarnya satu aspek. Coding setengahnya sebagai kode normal dan setengah lainnya sebagai aspek yang menambah masalah.

Jika Anda menggunakan AOP untuk aspek yang sama sekali berbeda, misalnya untuk logging, Anda tidak akan mengalami masalah anti-pola. Dalam hal itu seorang pemula untuk proyek mungkin bertanya-tanya "Di mana semua pesan log ini berasal? Saya tidak melihat output log dalam kode", tapi itu bukan masalah besar. Perubahan yang dia buat pada logika program tidak akan merusak fasilitas log dan perubahan yang dibuat pada fasilitas log tidak akan merusak logika programnya - aspek-aspek ini benar-benar terpisah. Menggunakan AOP untuk logging memiliki keuntungan bahwa kode program Anda dapat sepenuhnya berkonsentrasi pada melakukan apa yang seharusnya dilakukan dan Anda masih dapat memiliki logging yang canggih, tanpa kode Anda sedang berantakan oleh ratusan pesan log di mana-mana. Juga ketika kode baru diperkenalkan, pesan log ajaib akan muncul pada waktu yang tepat dengan konten yang tepat.

Jadi penggunaan AOP yang baik dalam contoh saya akan selalu mencatat jika ada nilai yang telah diperbarui melalui metode yang ditetapkan. Ini tidak akan membuat pola anti dan hampir tidak pernah menjadi penyebab masalah.

Orang mungkin mengatakan, jika Anda dapat dengan mudah menyalahgunakan AOP untuk menciptakan begitu banyak masalah, itu ide buruk untuk menggunakan semuanya. Namun teknologi mana yang tidak bisa disalahgunakan? Anda dapat menyalahgunakan enkapsulasi data, Anda dapat menyalahgunakan warisan. Hampir setiap teknologi pemrograman yang berguna dapat disalahgunakan. Pertimbangkan bahasa pemrograman yang sangat terbatas sehingga hanya berisi fitur yang tidak dapat disalahgunakan; bahasa di mana fitur hanya dapat digunakan karena mereka awalnya dimaksudkan untuk digunakan. Bahasa seperti itu akan sangat terbatas sehingga bisa diperdebatkan bahkan dapat digunakan untuk pemrograman dunia nyata.

Mecki
sumber
4
Pembalakan tampaknya menjadi salah satu contoh spesifik di mana AOP tidak menghasilkan Aksi pada Jarak Jauh. Pada saat ini, wikipedia sebagai contoh menggunakan aspek untuk hal-hal seperti pemeriksaan keamanan, yang benar-benar membuat aliran program jauh lebih dipahami.
kizzx2
7
@ kizzx2: Poin bagus tentang logging, sebenarnya - ini adalah contoh terbaik yang saya lihat sejauh ini kekuatan AOP, tanpa tahu banyak tentang AOP. Terima kasih telah berbagi!
kesalahan
@Mecki, Contoh Anda terlalu disederhanakan dan tidak mencerminkan kasus penggunaan umum. Dalam contoh Anda, Display.updatejangan mengambil argumen apa pun. Bagaimana jika kita perlu menyampaikan argumen (mis. Biasanya suatu logfungsi akan membutuhkan messageparameter)? Bukankah kita kemudian perlu menambahkan banyak kode boilerplate untuk melakukannya dengan cara AOP?
Pacerier
3
@Pacerier Contoh saya disederhanakan karena SO bukan forum pengajaran. Saya hanya menjawab pertanyaan si penanya, mungkin jauh lebih detail daripada yang seharusnya. Jika Anda ingin tahu lebih banyak tentang AOP, coba baca beberapa dokumentasi programmer dan jika Anda memiliki pertanyaan terperinci, mengapa tidak bertanya di sini? Tidak, tidak dalam komentar, buka dan buat pertanyaan baru karena itulah yang dimaksud dengan SO. Saya yakin seseorang akan dapat menghilangkan keraguan Anda dalam balasan.
Mecki
2
@Pacerier Maaf, tapi saya gagal melihat maksud Anda. Lihat di sini: stackoverflow.com/a/8843713/15809 Kode ini mencatat setiap panggilan ke setiap metode publik termasuk semua jenis dan nilai argumen metode. Anda menulis ini tepat sekali dan tidak ada kode boilerplate ditambahkan ke metode apa pun, hanya kode yang ditunjukkan dalam jawaban.
Mecki
29

pogramming berorientasi aspek menyediakan cara yang bagus untuk mengimplementasikan masalah lintas sektoral seperti logging, keamanan. Concert lintas sektor ini adalah potongan-potongan logika yang harus diterapkan di banyak tempat tetapi sebenarnya tidak ada hubungannya dengan logika bisnis.

Anda seharusnya tidak melihat AOP sebagai pengganti OOP, lebih sebagai add-on yang bagus, yang membuat kode Anda lebih bersih, secara longgar digabungkan dan berfokus pada logika bisnis. Jadi dengan menerapkan AOP Anda akan mendapat 2 manfaat utama:

  1. Logika untuk masing-masing masalah sekarang di satu tempat, yang bertentangan dengan tersebar di seluruh basis kode.

  2. kelas lebih bersih karena hanya berisi kode untuk perhatian utama mereka (atau fungsi inti) dan masalah sekunder telah dipindahkan ke aspek.

nkr1pt
sumber
27

OOP dan AOP tidak saling eksklusif. AOP bisa menjadi tambahan yang bagus untuk OOP. AOP sangat berguna untuk menambahkan kode standar seperti pencatatan, pelacakan kinerja, dll. Ke metode tanpa menyumbat kode metode dengan kode standar ini.

Norbert B.
sumber
10

Saya pikir tidak ada jawaban umum untuk pertanyaan ini tetapi satu hal yang perlu diperhatikan adalah, bahwa AOP tidak menggantikan OOP tetapi menambahkan fitur dekomposisi tertentu yang membahas apa yang disebut tirani dari komposisi dominan ( 1 ) (atau kekhawatiran lintas sektor).

Ini pasti membantu dalam kasus-kasus tertentu selama Anda mengendalikan alat dan bahasa untuk digunakan untuk proyek tertentu, tetapi juga menambahkan tingkat kompleksitas baru tentang interaksi aspek dan kebutuhan alat tambahan seperti AJDT untuk tetap memahami program anda.

Gregor Kiczales pernah memberikan ceramah pengantar yang menarik tentang AOP di Google Tech Talks yang saya sarankan tonton: Pemrograman Berorientasi Aspek: Penelitian Radikal dalam Modularitas .

fhe
sumber
8

Pertama-tama AOP tidak akan menggantikan OOP. AOP memperluas OOP. Gagasan dan praktik OOP tetap relevan. Memiliki desain objek yang baik mungkin akan membuatnya lebih mudah untuk diperluas dengan aspek-aspek.

Saya pikir ide-ide yang dibawa AOP penting. Kami perlu mencari cara untuk mengimplementasikan keprihatinan lintas kelas atas berbagai kelas dalam program Anda tanpa harus mengubah kelas itu sendiri. Tapi saya pikir AOP pada akhirnya hanya akan menjadi bagian dari alat lain yang kami gunakan dan bukan alat atau teknik terpisah. Kami sudah melihat ini terjadi.

Beberapa bahasa dinamis seperti Ruby dan Python memiliki konstruksi bahasa seperti mixin yang memecahkan masalah yang sama. Ini sangat mirip dengan AOP tetapi lebih terintegrasi dalam bahasa.

Spring dan Castle dan beberapa framework injeksi ketergantungan lainnya memiliki opsi untuk menambahkan perilaku ke kelas yang mereka injeksi. Ini adalah cara melakukan tenun-runtime dan saya pikir ini memiliki banyak potensi.

Saya tidak berpikir Anda harus belajar paradigma yang sama sekali baru untuk menggunakan AOP. Ide-ide itu menarik tetapi perlahan-lahan diserap oleh alat dan bahasa yang ada. Tetap terinformasi dan coba alat ini.

Mendelt
sumber
1

AOP adalah paradigma pemrograman baru yang berhubungan dengan konsep ini. Suatu aspek adalah entitas perangkat lunak yang mengimplementasikan bagian non-fungsional spesifik dari aplikasi.

Saya pikir artikel ini adalah tempat yang baik untuk memulai dengan Pemrograman Berorientasi Aspek: http://www.jaftalks.com/wp/index.php/introduction-to-aspect-oriented-programming/

JafTalks
sumber
1

Saya terlambat menjawab pertanyaan ini tetapi ini salah satu topik favorit saya, jadi izinkan saya membagikan pandangan saya.

OOP terutama digunakan untuk mengatur logika bisnis Anda sementara AOP membantu mengatur hal - hal non-fungsional Anda seperti Audit, Logging, Manajemen Transaksi, Keamanan dll

Dengan cara ini Anda dapat memisahkan logika bisnis Anda dengan logika non-fiksi yang membuat kode lebih bersih.

Keunggulan lain adalah Anda dapat menerapkan saran (contoh audit) dengan sangat konsisten tanpa mengimplementasikan antarmuka apa pun yang memberikan fleksibilitas besar untuk modifikasi tanpa menyentuh logika bisnis

GPopat
sumber