Jumat, 29 Juni 2018

AOP (Aspect-Oriented Programming)


1. Perbandingan Prosedural, OOP, dan AOP

- Pemrograman Prosedural

Pemrograman prosedural adalah suatu proses untuk mengimplementasikan urutan langkah untuk menyelesaikan suatu masalah dalam bentuk program. Selain pengertian diatas Pemrograman prosedural merupakan suatu aktifitas pemrograman dengan memperhatikan urutan langkah-langkah perintah secara sistematis, logis , dan tersusun berdasarkan algoritma yang sederhana dan mudah dipahami.
  1. Diselesaikan dalam bentuk prosedur atau fungsi
  2. Program merupakan urut-urutan instruksi
  3. Program dipecah-pecah ke dalam sub program yang lebih sederhana
  4. Fokus utama pada prosedur dan fungsi
  5. Fungsi dan prosedur digunakan untuk memanipulasi data, Sedangkan data sendiri bersifat pasif

- Pemrograman berorientasi Obyek

Pemrograman berorientasi objek (OOP) merupakan paradigma pemrograman yang berorientasikan kepada objek. Semua data dan fungsi di dalam paradigma ini dibungkus dalam kelas-kelas atau objek-objek. Jika dibandingkan dengan logika pemrograman terstruktur maka setiap objek dapat menerima pesan, memproses data, dan mengirim pesan ke objek lainnya.
  1. Fungsi dan data menjadi satu kesatuan yang disebut obyek
  2. Obyek-obyek dalam OOP bersifat aktif
  3. Cara pandang : program bukan urut-urutan instruksi tapi diselesaikan oleh obyek-obyek yang bekerjasama untuk menyelesaikan masalah
Pemrograman berorientasikan objek dikatakan lebih baik apabila Model data berorientasi objek dikatakan dapat memberi fleksibilitas yang lebih, kemudahan mengubah program, dan digunakan luas dalam teknik piranti lunak skala besar. Lebih jauh lagi, pendukung OOP mengklaim bahwa OOP lebih mudah dipelajari bagi pemula dibanding dengan pendekatan sebelumnya, dan pendekatan OOP lebih mudah dikembangkan dan dirawat.

- Pemrograman berorientasi Aspek

Pemrograman berorientasi Aspek (AOP) sering didefinisikan sebagai teknik yang mempromosikan pemisahan kekhawatiran dalam sistem perangkat lunak. Sistem terdiri dari beberapa komponen, masing-masing bertanggung jawab untuk bagian tertentu dari fungsi. Namun seringkali komponen ini juga membawa tanggung jawab tambahan di luar fungsi inti mereka. Layanan sistem seperti logging, manajemen transaksi, dan keamanan sering menemukan jalan mereka ke dalam komponen yang tanggung jawab utamanya adalah sesuatu yang lain. Layanan sistem ini biasanya disebut sebagai cross-cutting concerns karena mereka cenderung memotong beberapa komponen dalam suatu sistem.

2. Konsep Dasar AOP

AOP (Aspect Oriented Programming) merupakan sebuah metodologi sebagai tambahan untuk melengkapi metodologi OOP dimana OOP dianggap tidak cukup baik untuk memecahkan masalah crosscutting concern yang umumnya digunakan untuk aplikasi enterprise. Aspect Oriented Programming memerlukan pemecahan logika program menjadi bagian-bagian yang berbeda yang disebut so-called concerns. Fungsi yang menjangkau banyak titik dari suatu aplikasi disebut sebagai cross-cutting concerns. cross-cutting concerns ini secara konseptual terpisah dari logika bisnis aplikasi. Ada berbagai contoh umum baik dari aspek seperti logging, audit, transaksi deklaratif, keamanan, caching, dll.

Unit kunci dari modularitas dalam OOP adalah kelas, sedangkan dalam AOP unit modularitas adalah aspeknya. Dependency Injection membantu memisahkan objek aplikasi antara satu sama lain, sementara AOP membantu memisahkan cross-cutting concerns dari objek yang mereka pengaruhi. AOP seperti pemicu pada dalam bahasa pemrograman Perl, .NET, Java, dan lainnya.

Dalam pengembangan perangkat lunak berorientasi aspek, cross-cutting concerns adalah aspek dari program yang memengaruhi masalah lainnya. Kekhawatiran ini sering tidak dapat diuraikan secara bersih dari sistem yang lain baik dalam desain maupun implementasinya, dan dapat menghasilkan scattering (duplikasi kode), tangling (ketergantungan signifikan antar sistem), atau keduanya.

Misalnya, jika menulis aplikasi untuk menangani rekam medis, pengindeksan catatan tersebut merupakan perhatian utama, sementara mencatat riwayat perubahan pada basis data rekam atau basis data pengguna, atau sistem autentikasi, akan menjadi cross-cutting concerns karena mereka berinteraksi dengan lebih banyak bagian dari program.

Terdapat beberapa konsep dan terminologi yang dipakai dalam AOP. Berikut istilah-istilah terkait dengan AOP:

1. Aspect
Modul yang memiliki sekumpulan API yang menyediakan persyaratan cross-cutting. Misalnya, modul pencatatan akan disebut aspek AOP untuk pencatatan log. Aplikasi dapat memiliki sejumlah aspek tergantung pada kebutuhan.
2. Join point
Suatu titik selama pelaksanaan suatu program, seperti pelaksanaan suatu metode atau penanganan pengecualian. Ini mewakili titik di aplikasi Anda di mana Anda dapat memasukkan aspek AOP. Anda juga dapat mengatakan, itu adalah tempat yang sebenarnya dalam aplikasi di mana tindakan akan diambil.
3. Advice
Tindakan yang diambil oleh suatu aspek pada join points tertentu. Ini adalah tindakan nyata yang harus diambil sebelum atau sesudah eksekusi metode. Ini adalah potongan kode aktual yang dipanggil selama eksekusi program oleh kerangka Spring AOP.
Berdasarkan strategi eksekusi Advices, terdapat beberapa jenis yaitu:
- Before Advice: Advice ini berjalan sebelum pelaksanaan metode join point. Kita dapat menggunakan anotasi @Before untuk menandai jenis advice sebagai Before advice.
- After Advice: Advice yang dijalankan setelah metode join point selesai dieksekusi, baik secara normal atau dengan melempar pengecualian. Kita dapat membuat After advice menggunakan anotasi @After.
- After Returning Advice: Kadang-kadang kita ingin metode advice untuk dijalankan hanya jika metode join point dijalankan secara normal. Kita bisa menggunakan anotasi @AfterReturning untuk menandai metode after returning advice.
- After Throwing Advice: Advice ini dijalankan hanya ketika metode join point melempar pengecualian(exception), kita dapat menggunakannya untuk mengembalikan transaksi secara deklaratif. Kita dapat menggunakan anotasi @AfterThrowing untuk jenis advice ini.
- Around Advice: Ini adalah advice yang paling penting dan kuat. Advice ini mengelilingi metode join point dan kita juga dapat memilih apakah akan mengeksekusi metode join point atau tidak. Kita dapat menulis kode advice yang dijalankan sebelum dan sesudah eksekusi metode titik gabungan. Ini adalah tanggung jawab di sekitar saran untuk memanggil metode join point dan mengembalikan nilai jika metode mengembalikan sesuatu. Kita dapat menggunakan anotasi @Around untuk membuat metode around advice.
4. PointCut
Predikat yang cocok dengan join points. Advice dikaitkan dengan ekspresi pointcut dan berjalan pada join points apa pun yang dicocokkan oleh pointcut (misalnya, eksekusi metode dengan nama tertentu). Ini adalah satu atau lebih gabungan titik di mana Advice harus dijalankan. Anda dapat menentukan PointCuts menggunakan ekspresi atau pola.
5. Introduction
Juga dikenal sebagai deklarasi antar-jenis, mendeklarasikan metode atau bidang tambahan atas nama tipe. Memungkinkan untuk menambahkan metode atau atribut baru ke kelas yang ada.
6. Target object
Objek yang disarankan oleh satu atau lebih aspek. Objek ini akan selalu menjadi objek proksi. Juga disebut sebagai objek yang disarankan.
7. AOP proxy
Objek yang dibuat oleh kerangka kerja AOP untuk mengimplementasikan kontrak aspek (menyarankan eksekusi metode dan sebagainya)
8. Weaving
Weaving adalah proses menghubungkan aspek dengan jenis aplikasi atau objek lain untuk membuat objek yang disarankan. Ini dapat dilakukan pada waktu kompilasi, waktu buka, atau saat runtime. Menautkan aspek dengan jenis aplikasi atau objek lain untuk membuat objek yang disarankan.

3. Contoh Script AOP dalam Spring

- Before Advice
@Component
@Aspect
public class LoggingAspect {

    private Logger logger = Logger.getLogger(LoggingAspect.class.getName());

    @Pointcut("@target(org.springframework.stereotype.Repository)")
    public void repositoryMethods() {};

    @Before("repositoryMethods()")
    public void logMethodCall(JoinPoint jp) {
        String methodName = jp.getSignature().getName();
        logger.info("Before " + methodName);
    }
}

- After Advice
@Component
@Aspect
public class PublishingAspect {

    private ApplicationEventPublisher eventPublisher;

    @Autowired
    public void setEventPublisher(ApplicationEventPublisher eventPublisher) {
        this.eventPublisher = eventPublisher;
    }

    @Pointcut("@target(org.springframework.stereotype.Repository)")
    public void repositoryMethods() {}

    @Pointcut("execution(* *..create*(Long,..))")
    public void firstLongParamMethods() {}

    @Pointcut("repositoryMethods() && firstLongParamMethods()")
    public void entityCreationMethods() {}

    @AfterReturning(value = "entityCreationMethods()", returning = "entity")
    public void logMethodCall(JoinPoint jp, Object entity) throws Throwable {
        eventPublisher.publishEvent(new FooCreationEvent(entity));
    }
}

- Around Advice
@Aspect
@Component
public class PerformanceAspect {

    private Logger logger = Logger.getLogger(getClass().getName());

    @Pointcut("within(@org.springframework.stereotype.Repository *)")
    public void repositoryClassMethods() {};

    @Around("repositoryClassMethods()")
    public Object measureMethodExecutionTime(ProceedingJoinPoint pjp) throws Throwable {
        long start = System.nanoTime();
        Object retval = pjp.proceed();
        long end = System.nanoTime();
        String methodName = pjp.getSignature().getName();
        logger.info("Execution of " + methodName + " took " +
          TimeUnit.NANOSECONDS.toMillis(end - start) + " ms");
        return retval;
    }
}