Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. PHP

Pemrograman berorientasi aspek dalam PHP dengan Go!

by
Read Time:15 minsLanguages:

Indonesian (Bahasa Indonesia) translation by Sandi Muamar (you can also view the original English article)

Konsep dari Aspect-Oriented pemrograman (AOP) cukup baru untuk PHP. Sekarang tidak ada dukungan AOP resmi di PHP, tetapi ada beberapa ekstensi dan perpustakaan yang menerapkan fitur ini. Pada pelajaran ini kita akan menggunakan Go! PHP Library untuk belajar AOP di PHP, dan meninjau Kapan hal ini dapat membantu.


Sejarah singkat AOP

Pemrograman berorientasi aspek adalah seperti sebuah gadget baru untuk geeks.

Istilah Aspect-Oriented pemrograman mengambil bentuk pada pertengahan 1990-an, dalam sebuah kelompok kecil di Xerox Palo Alto Research Center (PARC). AOP dianggap kontroversial di awal hari — seperti halnya dengan setiap teknologi baru dan menarik-sebagian besar karena kurangnya definisi yang jelas. Kelompok tersebut kemudian membuat keputusan sadar untuk melepaskan itu dalam form setengah matang, agar community lebih besar memberikan umpan balik. Di jantung masalah adalah konsep "Separation of Concerns" concept". AOP adalah salah satu solusi yang mungkin untuk memisahkan masalah.

AOP matang di akhir 1990-an, ketika dirilis Xerox AspectJ, dan IBM mengikutinya dengan mereka Hyper/J pada tahun 2001. Hari ini, AOP adalah teknologi mapan yang telah diadopsi oleh bahasa pemrograman yang paling umum.


Kosakata dasar

Di jantung AOP adalah aspek, tetapi sebelum kita dapat mendefinisikan "aspek", kita harus membahas dua istilah lain: point-cut dan advise. Point-cut mewakili sebuah momen dalam kode sumber kami, menentukan saat yang tepat untuk menjalankan kode kita. Kode yang mengeksekusi pada tpoibt-cut dipanggul, advise, dan kombinasi dari satu atau lebih point-cut dan menyarankan adalah aspek.

Biasanya, masing-masing class memiliki satu perilaku inti atau masalah, tetapi dalam banyak situasi, class mungkin menunjukkan perilaku sekunder. Misalnya, sebuah class mungkin perlu untuk memanggil logger atau memberitahukan observer. Karena fungsi ini sekunder, perilaku mereka sebagian besar adalah sama untuk semua class yang menunjukkan mereka. Skenario ini disebut cross-concern; ini dapat dihindari dengan menggunakan AOP.


AOP berbagai tool untuk PHP

Chris Peters sudah membahas Flow Framework untuk AOP di PHP. AOP implementasi lainnya dapat ditemukan dalam framework Lithium.

Kerangka lain mengambil pendekatan yang berbeda, dan menciptakan sebuah ekstensi PHP lengkap dalam C/C++, melakukan magic pada tingkat yang sama sebagai interpreter PHP. Ini disebut AOP PHP Extension, dan saya bisa bahas dalam artikel yang akan datang.

Tapi seperti yang saya catat sebelumnya, untuk tutorial ini, kita akan meninjau Go! AOP-PHP perpustakaan.


Menginstal dan mempersiapkan Go!

Go! Perpustakaan bukanlah extension; itu benar-benar ditulis dalam PHP PHP 5.4 dan lebih tinggi. Menjadi hanya plain PHP Perpustakaan memungkinkan untuk penggunaan yang mudah, bahkan di lingkungan yang ketat, shared hosting yang tidak memungkinkan Anda untuk mengkompilasi dan menginstal ekstensi PHP Anda sendiri.

Instal Go! dengan Composer

Composer adalah metode yang disukai untuk menginstal paket PHP. Jika Anda tidak memiliki akses ke composer, Anda selalu dapat mendownloadnya dari Go! Repositori GitHub.

Pertama, tambahkan baris berikut ke file composer.json Anda.

Selanjutnya, gunakan Composer untuk menginstal go-aop-php. Jalankan perintah berikut dari terminal:

Composer akan menginstal paket-paket yang diperlukan dan dependensi hanya dalam beberapa detik. Jika berhasil, Anda akan melihat sesuatu yang mirip dengan output berikut:

Setelah instalasi telah selesai, Anda akan menemukan sebuah direktori, disebut vendor, dalam folder source Anda. Go! Perpustakaan dan dependensinya sudah dipasang.

Mengintegrasikan Go! Proyek kami

Kita perlu untuk membuat panggilan yang berada di antara routing entry point dari aplikasi kita. Autoloader kemudian secara otomatis mencakup class. Pergi! merujuk kepada ini sebagai Aspect Kernel.

Hari ini, AOP adalah teknologi mapan yang telah diadopsi oleh bahasa pemrograman yang paling umum.

Untuk contoh ini, saya telah menciptakan sebuah direktori, yang disebut Application, dan menambahkan file class baru, ApplicationAspectKernel.php di dalamnya.

Kernel aspek extend Go!' s abstrak AspectKernel class, yang menyediakan fungsionalitas dasar yang membutuhkan aspek kernel melakukan tugasnya. Ada dua metode yang kami harus terapkan: configureAop(), yang mendaftar aspek nanti kita, dan getApplicationLoaderPath(), yang menyediakan sebuah string yang mewakili path lengkap aplikasi autoloader.

Untuk sekarang, cukup buat sebuah file kosong autoload.php di direktori Application Anda, dan mengubah metode getApplicationLoaderPath(), sesuai.

Jangan khawatir tentang autoload.php dulu; kita akan mengisi bagian yang hilang segera.

Ketika saya pertama kali dipasang Go! dan mencapai titik proses saya, saya merasa perlu untuk menjalankan beberapa kode. Jadi mari kita mulai membangun sebuah aplikasi kecil!


Menciptakan Logger sederhana

Aspek kami akan logger sederhana, tetapi kita perlu terlebih dulu beberapa kode untuk menonton sebelum kita mulai dengan bagian utama dari aplikasi kita.

Membuat aplikasi Minimal

Aplikasi kecil kami akan broker elektronik, mampu membeli dan menjual saham.

Kode ini cukup sederhana. Broker class memiliki dua bidang private yang menyimpan broker nama dan ID.

Class ini juga menawarkan dua metode, buy() dan sell() untuk membeli dan menjual saham, masing-masing. Setiap metode tersebut menerima tiga argumen:'s simbol saham, jumlah saham, dan harga per saham. Metode sell() menjual saham dan kemudian menghitung total uang yang diterima. Sebaliknya, metode buy() membeli saham dan menghitung total uang yang dibelanjakan.

Latihan Broker kami

Kita dengan mudah dapat mencoba Broker dengan menulis tes PHPUnit. Buat sebuah direktori, disebut Test di dalam Application, dan, di dalamnya, tambahkan file baru, BrokerTest.php. Menambahkan kode berikut ke dalam file tersebut:

kembaliTes ini hanya memeriksa nilai-nilai yang dikembalikan metode broker. Kita dapat menjalankan tes ini dan melihat bahwa kode kita setidaknya sintaksis benar.

Tambahkan Auto Loader

Mari kita membuat autoloader yang secara fisik memuat class yang aplikasi kita butuhkan. Ini akan menjadi sebuah loader sederhana, berdasarkan autoloader PSR-0.

Itu adalah semua yang kita butuhkan untuk autoload.php file. Sekarang, mengubah BrokerTest.php untuk meminta autoloader bukan class Broker.php.

Menjalankan BrokerTest membuktikan bahwa kode masih bekerja.

Menghubungkan ke Application Aspect Kernel

Langkah terakhir kami adalah mengkonfigurasi Go!. Kita perlu untuk menghubungkan semua komponen sehingga mereka bekerja dalam harmoni. Pertama, membuat file, disebut AspectKernelLoader.php, dan tambahkan kode berikut:

Kita perlu untuk menghubungkan semua komponen sehingga mereka bekerja dalam harmoni.

File ini berada di antara front controller dan autoloader. Menggunakan infrastruktur AOP untuk menginisialisasi dan memanggil autoload.php ketika diperlukan.

Di baris pertama, kita secara eksplisit termasuk AspectKernel.php dan ApplicationAspectKernel.php. File-file ini harus secara eksplisit disertakan, karena, ingat, kita memiliki autoloader ada saat ini.

Dalam segmen kode berikut, kita memanggil metode init() di objek ApplicationAspectKernel dan memasukan array pilihan:

  • autoload mendefinisikan path untuk menginisialisasi untuk Perpustakaan AOP. Menyesuaikan path menurut struktur direktori Anda.
  • appDir merujuk pada direktori aplikasi.
  • cacheDir menentukan direktori cache (kami akan mengabaikan hal ini untuk tutorial ini).
  • includePaths mewakili filter untuk aspek. Kami ingin semua direktori yang ditentukan untuk ditonton, sehingga meninggalkan array kosong untuk menonton semuanya.
  • debug menyediakan informasi debug tambahan, yang berguna untuk pengembangan, tetapi Anda harus mengatur ke false untuk aplikasi yang digunakan.

Untuk menyelesaikan hubungan antara potongan-potongan yang berbeda, menemukan semua referensi ke autoload.php dalam proyek Anda dan menggantinya dengan AspectKernelLoader.php. Dalam contoh kita sederhana, hanya file tes memerlukan modifikasi:

Untuk proyek yang lebih besar, Anda mungkin menemukan itu berguna untuk menggunakan bootstrap.php untuk PHPUnit; require_once() untuk autoload.php atau AspectKernelLoader.php kami tidak harus dimasukkan.

Log metode Broker

Buat sebuah file, disebut BrokerAspect.php, dan tambahkan kode berikut:

Kita mulai dengan menentukan beberapa statement use infrastruktur AOP. Kemudian, kami membuat class aspek, yang disebut BrokerAspect, yang harus menerapkan Aspect. Selanjutnya, kita menetapkan logika cocok untuk aspek kami:

  • @Before menentukan kapan harus menerapkan masukan. Kemungkinan are @Before, @After, @Around dan @AfterThrowing.
  • "execution(public Broker-> * (*))" menentukan aturan cocok sebagai pelaksanaan metode public di class, yang disebut Broker, dengan sejumlah parameter. Sintaks: [operation - execution/access]([method/attribute type - public/protected] [class]->[method/attribute]([params])

Harap dicatat bahwa mekanisme pencocokan memang agak aneh. Anda dapat menggunakan hanya satu ' *' (bintang) di setiap bagian dari aturan. Sebagai contoh, public Broker-> pertandingan class, yang panggil Broker. public Bro *-> pertandingan setiap kelas dimulai dengan Bro, dan public * ker-> cocok setiap class berakhir dengan ker.

public * rok *-> tidak akan cocok apa-apa; Anda tidak boleh menggunakan lebih dari satu bintang pertandingan sama.

Metode berikut matcher akan dipanggil ketika event terjadi. Dalam kasus kami, metode mengeksekusi sebelum setiap panggilan pada salah satu Broker metode public. Parameter, dipangil $invocation (jenis MethodInvocation), secara otomatis dimasukan ke metode kami. Objek ini menyediakan cara yang berbeda untuk mendapatkan informasi tentang metode yang dipangil. Dalam contoh pertama ini, kita menggunakannya untuk mendapatkan nama metode dan mencetaknya.

Mendaftar Aspect

Hanya mendefinisikan aspek ini tidak cukup; kita perlu untuk mendaftar ke infrastruktur AOP. Jika tidak, itu tidak akan diterapkan. Edit ApplicationAspectKernel.php dan memanggil registerAspect() kontainer dalam configureAop() metode:

Menjalankan tes dan periksa output. Anda harus melihat sesuatu yang mirip dengan berikut:

Jadi kita telah berhasil menjalankan kode setiap kali sesuatu terjadi pada broker.

Menemukan parameter dan pencocokan @After

Mari kita menambahkan metode lain untuk BrokerAspect.

Metode ini berjalan setelah metode publik mengeksekusi (catatan @After matcher). Kami kemudian tambahkan baris lain untuk output parameter yang digunakan untuk memanggil metode. Output dari ujian kami sekarang adalah:

Mendapatkan kembali nilai-nilai dan memanipulasi eksekusi

Sejauh ini, kami telah belajar bagaimana untuk menjalankan kode tambahan sebelum dan sesudah mengeksekusi sebuah metode. Sementara ini bagus, hal ini tidak terlalu berguna jika kita tidak bisa melihat apa yang dikembalikan metode. Mari kita menambahkan metode lain pada aspek dan memodifikasi kode yang sudah ada:

Hanya mendefinisikan aspek ini tidak cukup; kita perlu untuk mendaftar ke infrastruktur AOP.

Kode baru ini bergerak informasi parameter ke metode @Before. Kita juga menambahkan metode lain dengan matcher khusus @Around. Hal ini rapi, karena panggilan metode cocok asli dibungkus dalam fungsi aroundMethodExecution(), secara efektif supressing original invokasi. Di dalam advise, kami perlu memanggil $invocation-> proceed(), untuk mengeksekusi panggilan asli. Jika Anda tidak melakukan ini, panggilan asli tidak akan terjadi.

Pembungkus ini juga memungkinkan kita untuk memanipulasi Nilai kembalian. Apa yang kita kembalikan di advise kami adalah apa yang dikembalikan dalam panggilan asli. Dalam kasus kami, kami tidak mengubah apa pun, dan output Anda akan terlihat seperti ini:

Mari kita bermain sedikit dan menawarkan diskon untuk broker tertentu. Kembali ke class eksperimen, dan menulis tes berikut:

Hal ini akan gagal dengan:

Berikutnya, kami perlu untuk memodifikasi broker memberikan id nya. Hanya menerapkan metode getId(), seperti yang ditunjukkan di bawah ini:

Sekarang, memodifikasi aspek untuk menyesuaikan harga pembelian untuk broker dengan ID dari 2.

Bukannya menambahkan metode baru, hanya memodifikasi fungsi aroundMethodExecution(). Sekarang hanya mencockan metode, yang dipanggil 'buy', dan memicu $invocation-> getThis(). Ini secara efektif kembali objek Broker asli sehingga kami dapat menjalankan kode. Dan jadi kami melakukan! Kami meminta broker ID itu, dan menawarkan diskon jika ID ada sama dengan 2. Ujian sekarang sukses.

Matching Exception

Kita sekarang dapat mengeksekusi kode tambahan ketika metode dimasukkan, setelah itu mengeksekusi dan sekitarnya. Tapi bagaimana jika metode melemparkan exception?

Tambahkan metode uji untuk membeli sejumlah besar saham:

Sekarang, membuat class exception. Kita memerlukan ini karena built-in Exception class tidak tertangkap oleh Go! AOP atau PHPUnit.

Memodifikasi broker untuk memunculkan exception untuk nilai besar:

Menjalankan tes dan memastikan bahwa mereka gagal:

Sekarang, setiap exception (dalam tes) dan pastikan mereka sukses:

Menciptakan metode baru dalam aspek kami untuk mencocokkan @AfterThrowing, dan jangan lupa untuk menentukan use Go\Lang\Annotation\AfterThrowing;

@AfterThrowing matcher menekan exception yang dilemparkan dan memungkinkan Anda untuk mengambil tindakan Anda sendiri. Dalam kode kita, kita hanya echo pesan, tetapi Anda dapat melakukan apa pun yang memerlukan aplikasi Anda.


Akhir pikiran

Inilah sebabnya mengapa saya mendorong Anda untuk menggunakan aspek dengan hati-hati.

Pemrograman berorientasi Aspect adalah seperti sebuah gadget baru untuk geeks; Anda dapat segera melihat potensi besar. Aspects memungkinkan kita untuk memperkenalkan kode tambahan di bagian yang berbeda dari sistem kami tanpa memodifikasi kode asli. Hal ini dapat membuktikan menjadi sangat berguna ketika Anda perlu untuk mengimplementasikan modul yang mencemari metode dan class dengan erat referensi dan metode panggilan Anda.

Fleksibilitas ini, bagaimanapun, datang dengan harga: ketidakjelasan. Tidak ada cara untuk mengetahui jika aspect watches metode hanya dengan melihat metode atau classnya. Sebagai contoh, ada ada indikasi dalam class Broker kami bahwa apa pun yang terjadi ketika mengeksekusi metodenya. Inilah sebabnya mengapa saya mendorong Anda untuk menggunakan aspect dengan hati-hati.

Kami menggunakan aspek untuk menawarkan diskon untuk broker tertentu adalah contoh penyalahgunaan. Menahan diri dari melakukan hal itu dalam sebuah proyek yang nyata. Diskon broker yang berkaitan dengan broker; Jadi, menjaga logika di class Broker. Aspek harus hanya melakukan tugas-tugas yang tidak secara langsung berhubungan dengan objek utama perilaku.

Bersenang-senang dengan ini!

Advertisement
Did you find this post useful?
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.