Dian Aditya

Penjahit Digital.

Data Access Object (DAO) Dan Service/Facade Pattern, Apa Dan Mengapa

Sering saya mendapat pertanyaan dari teman maupun adik kelas tentang “Gimana caranya bikin DAO?”, “Kenapa harus pake DAO?”, ataupun pertanyaan paling general “DAO itu apaan sih?”. Maklum, saya memang yang paling ngeyel mengkritik masalah bentuk dan kerapian baris kode aplikasi bikinan rekan-rekan seperjuangan yang berhubungan dengan database/persistence, bahkan tidak jarang mengesampingkan bussines proccess apikasi itu sendiri. Yah memang terlalu teknis sih, tapi di dunia open source kerapian kode itu nomor wahid (mungkin :D), ditonton dunia gitu, berbeda dengan barang close source yang orang cuma tau itu barang tiba-tiba ada, walaupun kerapian kode itu tetap penting. Mungkin tulisan adalah sedikit bentuk curhat saya kepada banyak pihak yang menganggap saya sebagai orang yang paling meyebalkan urusan coding selama ini (sok teraniaya banget :P). Memang saya sering jawab “cari di internet” atau “kan ada google” sebelum saya sadar bahwa mau gak mau, gak mau mau, mau mau enggak, ataupun mau mau mau, sebagian siswa Indonesia malas mebaca tulisan yang sedikit ribet, sedikit panjang, ditambah lagi pake bahasa Belanda. Komplit dah, dan akhirnya memutuskan untuk bertanya pada orang sok tau seperti saya :D Berikut sedikit jawaban dari saya, semoga bermanfaat… Data Access Object Data Access Object (DAO) merupakan sebuah object yang menyediakan sebuah abstract interface terhadap beberapa database atau mekanisme persistence, menyediakan beberapa operasi tertentu tanpa mengekspos detail database. Penerapan konsep ini sering disebut dengan separation of concern dimana setiap kode dipisahkan berdasarkan fungsinya sehingga kode diatasnya hanya perlu mengetahui secara abstrak cara mengakses data tanpa perlu mengetahui bagaimana akses ke sumber data diimplementasikan. DAO sering dikaitkan dengan Java EE dan akses ke relational database melalu JDBC API, karena memang DAO berasal dari pedoman praktek Sun Microsystem. Kebanyakan peggunaan DAO adalah satu objek DAO untuk satu objek entity. Berikut contoh sederhana penggunaan DAO dengan penerapan aksess ke sumber data menggunakan JPA. Dimisalkan saya mempunyai dua buah class entity yaitu barang dan kategori barang. KategoriBarang.java

public class KategoriBarang {
    private String kode;
    private String nama;
    private String deskripsi;
    private List<Barang> daftarBarang;
    /**
     * getter dan setter
     */
}

Barang.java

public class Barang {
  
    private String kode;
    private String nama;
    private long harga;
    private KategoriBarang kategori;
    /**
     * getter dan setter
     */
}

Berikut contoh penggunaa DAO untuk kedua entity tersebut

public class BarangDAO {
    private EntityManager entityManager;
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }
    private final String getAllQuery = "SELECT b FROM Barang b";
    private final String getByIdQuery = "FROM Barang b WHERE b.kode = :kode";
    public List<Barang> getAll() {
        return entityManager.createQuery(getAllQuery).getResultList();
    }
    public Barang getById(String kode) {
        return (Barang) entityManager.createQuery(getByIdQuery)
                .setParameter("kode", kode).getSingleResult();
    }
    public void save(Barang barang) {
        entityManager.persist(barang);
    }
    public void delete(Barang barang) {
        entityManager.remove(barang);
    }
    public KategoriBarang getKategori(String kodeBarang) {
        return getById(kodeBarang).getKategori();
    }
}
public class KategoriBarangDAO {
    private EntityManager entityManager;
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }
    private final String getAllQuery = "SELECT b FROM KategoriBarang b";
    private final String getByIdQuery = "FROM KategoriBarang b WHERE b.kode = :kode";
    public List<KategoriBarang> getAll() {
        return entityManager.createQuery(getAllQuery).getResultList();
    }
    public KategoriBarang getById(String kode) {
        return (KategoriBarang) entityManager.createQuery(getByIdQuery)
                .setParameter("kode", kode).getSingleResult();
    }
    public void save(KategoriBarang kategori) {
        entityManager.persist(kategori);
    }
    public void delete(KategoriBarang kategori) {
        entityManager.remove(kategori);
    }
    public List<Barang> getKategori(String kodeKategoriBarang) {
        return getById(kodeKategoriBarang).getDaftarBarang();
    }
}

Panjang bukan? Hehehehe, tenang saja di java semuanya bisa diakalin, kita tahu bahwa beberapa method seperti getAll, getById, save, dan delete merupakan method yang umum dan sering diguakan dalam persistence, dengan kata lain method-method tersebut dapat diabstraksi. Berikut diagramnya Java juga menyediakan generic type sejak versi 5, sehingga dalam pembuatan DAO kita dapat menciptakan sebuah mantra yang dinamakan generic DAO, fungsi utama dari generic type ini adalah untuk menghandle beberapa fungsi yang mengembalikan nilai secara dinamis, sebagai contoh diatas adalah method getById. Berikut contoh kodenya.

public abstract class GenericDAO<T> {
    protected EntityManager entityManager;
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }
    protected abstract Class<T> getEntityClass();
    public List<T> getAll() {
        String query = "FROM " + getEntityClass().getName();
        return entityManager.createQuery(query).getResultList();
    }
    public T getById(String id) {
        String query = "FROM " + getEntityClass().getName()
                + " WHERE kode = :kode";
        return (T) entityManager.createQuery(query).setParameter("kode", id)
                .getSingleResult();
    }
    public void save(T entity) {
        entityManager.persist(entity);
    }
    public void delete(T entity) {
        entityManager.remove(entity);
    }
}

Salah satu keuntungan menggunakan generic DAO adalah menghindari duplikasi data. Sehingga kita hanya perlu membuat turunan dari generic DAO tersebut dan menambahkan beberapa method spesifik bila diperlukan.

public class BarangDAO extends GenericDAO<Barang> {
    @Override
    protected Class<Barang> getEntityClass() {
        return Barang.class;
    }
    public KategoriBarang getKategori(String kodeBarang) {
        return getById(kodeBarang).getKategori();
    }
}

Service / Facade Facade merupakan sebuah objek yang berfungsi untuk menyederhanakan kumpulan kode besar seperti library. Dalam kasus database kita dapat menggunakan facade untuk mengelompokkan beberapa DAO dalam sebuah transaksi. Business logic juga dapat diletakkan pada bagian ini. Berikut contoh penggunaan facade

public interface BarangService {
  
    void saveBarang(Barang barang);
  
    void setKategoriBarang(String kodeBarang, String kodeKategori);
  
}
public class BarangServiceImpl implements BarangService {
  
    private BarangDAO barangDAO;
    private KategoriBarangDAO kategoriBarangDAO;
    public void setBarangDAO(BarangDAO barangDAO) {
        this.barangDAO = barangDAO;
    }
    public void setKategoriBarangDAO(KategoriBarangDAO kategoriBarangDAO) {
        this.kategoriBarangDAO = kategoriBarangDAO;
    }
    public void saveBarang(Barang barang) {
        barangDAO.save(barang);
    }
    public void setKategoriBarang(String kodeBarang, String kodeKategori) {
        KategoriBarang kategoriBarang = kategoriBarangDAO.getById(kodeKategori);
        Barang barang = barangDAO.getById(kodeBarang);
        barang.setKategori(kategoriBarang);
        barangDAO.save(barang);
    }
}

Penggabungan antara DAO dan Service pattern secara disiplin dapat menghasilkan kode yang bukan hanya mudah dibaca maupun ditesting, bahkan dapat dimodifikasi tanpa merubah modul yang menggunakan DAO maupun service, sebagai contoh ketika saya ingin mengganti akses ke database menggunakan JDBC, hanya perlu modifikasi pada bagian DAO tanpa merubah sama sekali bagian business logic pada service. Selain itu juga meningkatkan efisiensi dan kinerja dari lapisan data karena merupakan standart software yang dapat digunakan kembali (reusable).

Comments