Sudah tahu apa itu Dependency Injection?
Minimal sudah pernah dengar apa itu Dependency Injection?
Makanan apa itu?
Jika belum semua atau belum salah satu berarti kamu berada pada tulisan yang tepat 😀
Dependency Injection atau yang biasa disingkat DI terkenal didunia pemrograman setelah banyak bermunculan framework yang menerapkan konsep ini. Salah satunya dan yang paling terkenal adalah Spring.
DI dimaksudkan agar suatu kelas tidak terikat erat dengan kelas yang lain sehingga hubungan antar bagian kode menjadi longgar (loosely coupled).
Diartikan secara bahasa gampang DI berarti kita memberikan/menginjeksi suatu kelas ke kelas yang lain yang merupakan dependensinya (membutuhkannya).
Mungkin kalau pakai kata-kata gitu sampeyan pada mumet ya 😀
Saya juga mumet awalnya kalau cuman pakai kata-kata karena belum mudheng apa itu maksudnya hehee
Kalau begitu mari kita pakai contoh koding sadja..
Misal contoh kasus kita mempunyai Kelas Mahasiswa berikut yang merepresentasikan tabel mahasiswa pada database
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
package model; public class Mahasiswa { private String nim; private String nama; private int umur; private String asalSekolah; private String alamat; public String getNim() { return nim; } public void setNim(String nim) { this.nim = nim; } public String getNama() { return nama; } public void setNama(String nama) { this.nama = nama; } public int getUmur() { return umur; } public void setUmur(int umur) { this.umur = umur; } public String getAsalSekolah() { return asalSekolah; } public void setAsalSekolah(String asalSekolah) { this.asalSekolah = asalSekolah; } public String getAlamat() { return alamat; } public void setAlamat(String alamat) { this.alamat = alamat; } } |
Untuk melakukan operasi database dari kelas diatas seperti menyimpan mahasiswa, hapus, edit dan query data kita membuat sebuah kelas yang khusus menangani hal tersebut.
Kita buat kelas dengan nama MahasiswaDao
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
package dao; import com.mysql.jdbc.jdbc2.optional.MysqlDataSource; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import model.Mahasiswa; public class MahasiswaDao { MysqlDataSource dataSource; Connection connection; public MahasiswaDao() throws SQLException{ dataSource=new MysqlDataSource(); dataSource.setServerName("localhost"); dataSource.setUser("root"); dataSource.setPassword(""); dataSource.setDatabaseName("MvcNative"); connection=dataSource.getConnection(); } public void tambahMahasiswa(Mahasiswa mahasiswa) throws SQLException{ PreparedStatement ps=connection.prepareStatement("INSERT INTO mahasiswa values(?,?,?,?,?)"); ps.setString(1, mahasiswa.getNim()); ps.setString(2, mahasiswa.getNama()); ps.setInt(3, mahasiswa.getUmur()); ps.setString(4, mahasiswa.getAsalSekolah()); ps.setString(5, mahasiswa.getAlamat()); ps.execute(); connection.close(); } public List<Mahasiswa> getAllMahasiswa() throws SQLException{ List<Mahasiswa> mahasiswas=new ArrayList<Mahasiswa>(); PreparedStatement ps=connection.prepareStatement("SELECT * FROM mahasiswa"); ResultSet rs=ps.executeQuery(); while(rs.next()){ Mahasiswa mahasiswa=new Mahasiswa(); mahasiswa.setNim(rs.getString("nim")); mahasiswa.setNama(rs.getString("nama")); mahasiswa.setUmur(rs.getInt("umur")); mahasiswa.setAsalSekolah(rs.getString("asal_sekolah")); mahasiswa.setAlamat(rs.getString("alamat")); mahasiswas.add(mahasiswa); } connection.close(); return mahasiswas; } public Mahasiswa getMahasiswa(String nim) throws SQLException{ PreparedStatement ps=connection.prepareStatement("SELECT * FROM mahasiswa where nim=?"); ps.setString(1, nim); ResultSet rs=ps.executeQuery(); Mahasiswa mahasiswa=new Mahasiswa(); while(rs.next()){ mahasiswa.setNim(rs.getString("nim")); mahasiswa.setNama(rs.getString("nama")); mahasiswa.setUmur(rs.getInt("umur")); mahasiswa.setAsalSekolah(rs.getString("asal_sekolah")); mahasiswa.setAlamat(rs.getString("alamat")); } connection.close(); return mahasiswa; } public void updateMahasiswa(Mahasiswa mahasiswa) throws SQLException{ PreparedStatement ps=connection.prepareStatement("UPDATE mahasiswa set nama=?,umur=?,asal_sekolah=?," + "alamat=? where nim=?"); ps.setString(1, mahasiswa.getNama()); ps.setInt(2, mahasiswa.getUmur()); ps.setString(3, mahasiswa.getAsalSekolah()); ps.setString(4, mahasiswa.getAlamat()); ps.setString(1, mahasiswa.getNim()); ps.executeUpdate(); connection.close(); } public void hapusMahasiswa(String nim) throws SQLException{ PreparedStatement ps=connection.prepareStatement("DELETE FROM mahasiswa where nim=?"); ps.setString(1, nim); ps.executeUpdate(); connection.close(); } } |
Coba perhatikan kelas diatas.
Sekilas tidak ada yang salah kan? 🙂
Kalau diperhatikan betul-betul pun sebenarnya memang tidak ada yang salah, yang ada adalah kurang elegan.
Perhatikan pada bagian constructor dari kelas diatas.
Disitu kelas ini terlihat membutuhkan (dependent) terhadap Connection untuk melakukan berbagai operasi database.
Lihat pada bagian yang saya highlight
Bagimana cara mendapatkan Connection inilah yang akan kita bahas
1 2 3 4 5 6 7 8 9 10 11 12 |
MysqlDataSource dataSource; Connection connection; public MahasiswaDao() throws SQLException{ dataSource=new MysqlDataSource(); dataSource.setServerName("localhost"); dataSource.setUser("root"); dataSource.setPassword(""); dataSource.setDatabaseName("MvcNative"); connection=dataSource.getConnection(); } |
Lantas dimana tidak elegannya?
Begini,
Pada aplikasi nyata tentunya kita tidak hanya memiliki tabel mahasiswa bukan?
Masih ada tabel dosen, matakuliah, nilai, user, jadwal, jurusan dan lain-lain bisa sampai banyak sekali tergantung kebutuhan.
Nah.. bisa dibayangkan kalau nanti juga akan ada kelas dengan nama xxxDao lainnya dan setiap kelas dao tersebut memiliki constructor seperti diatas.
Runyamnya disini
Jika misal lokasi server berubah maka kita harus menggantinya 1 per 1 pada setiap kelas dao???
kalau ada ratusan kelas bagaimana???
belum lagi buat Unit Testing menggunakan mock object bagaimana???
sudah paham kan dimana kurang elegannya 😀
Untuk mengatasi hal tersebut maka kita gunakan Dependency Injection.
Mari kita refactor kelas MahasiswaDao sehingga constructor menjadi seperti ini
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
package dao; import com.mysql.jdbc.jdbc2.optional.MysqlDataSource; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import model.Mahasiswa; public class MahasiswaDao { Connection connection; public MahasiswaDao(Connection connection) throws SQLException{ this.connection=connection; } |
Kita Tambahkan parameter pada constructor supaya Connection bisa diberikan (di-injectkan) kepada kelas MahasiswaDao yang membutuhkannya.
Dengan DI ini kelas Dao tidak perlu mengurusi inisialisasi DataSource serta Connection-nya.
Lalu siapa yang melakukan inisialisasi? boleh siapa saja asal bukan kelas Dao itu sendiri.
Untuk contoh sadja kita inisialisasikan pada TestMahasiswaDao misalnya.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public class TestMahasiswaDao { public static void main(String[] xx){ Mahasiawa m=new Mahasiswa() m.setNim("L2F008002"); m.setNama("Agung Setiawan"); m.setUmur(23); m.setAsalSekolah("SMA N 1 Pekalongan"); m.setAlamat("Batang"); MysqlDataSource dataSource=new MysqlDataSource(); dataSource.setServerName("localhost"); dataSource.setUser("root"); dataSource.setPassword(""); dataSource.setDatabaseName("MvcNative"); Connection connection=dataSource.getConnection(); MahasiswaDao mahasiswaDao = new MahasiswaDao(connection); mahasiswaDao.tambahMahasiswa(m); } } |
Dengan struktur yang seperti itu maka :
– Perubahan cukup dilakukan pada satu tempat
– Unit Testing menjadi mudah
– Bisa menggunakan berbagai macam datasource dengan hanya merubah sedikit konfigurasi (oracle, sql server, dll)
Semoga bermanfaat
😀
Dulu, ketika sedang belajar dependency injection, tulisan ini adalah salah satu tulisan yang punya andil besar sehingga saya bisa memahami dependency injection. Dari semua tulisan berbahasa indonesia yang membahas mengenai dependency injection, tulisan ini paling mudah difahami dan paling jelas menjelaskan apa itu dependency injection dan apa keuntungan menggunakannya. Tidak lama setelah saya faham mengenai dependency injection, saya membuat tulisan di blog saya mengenai dependency injection. Tentu, tulisan mas agung ini punya andil besar sehingga saya bisa membuat tulisan itu. Terima kasih mas.