Pendahuluan Part 2


Pendahuluan awal mengenai Marker Interface bisa dilihat di sini

Jadi Marker Interface tidak mempunyai fungsi atau method apa-apa di dalamnya.

Cuma sebagai penanda saja bagi program lain yang menganalisa object implementasinya dari Marker Interface itu diwaktu Runtime.


Kita lanjut membahas kasus di artikel diatas tersebut :

Misalkan kita punya tipe Interface Rumah.

Dan ada banyak class implementornya , yaitu :

  • class RumahClassic
  • class RumahMinimalis
  • class RumahSkandinavia
  • class RumahJapanese
  • class RumahSusun

Dan ternyata interface Rumah mempunyai fungsi untuk Renovasi.

Ternyata renovasi yang dibolehkan ada 3 :

  • Renovasi vertikal, yaitu menambah lantai bangunan.
  • Renovasi horizontal, yaitu menambah bangunan kesamping, di lahan tanah yang kosong.
  • Atau cuma renovasi interior saja.

Maka pendekatannya :



1. Memakai if..then…else


Contohnya kita memakai code sbb :

----
public class RumahClassic implements Rumah { // code }

public class RumahMinimalis implements Rumah { // code }

public class RumahSkandinavian implements Rumah { // code }

public class RumahJapanese implements Rumah { // code }

public class RumahSusun implements Rumah { // code }


----
public Enum TipeRenovasi {
	 HORIZONTAL,
	 VERTIKAL;
}

----
@Override
public void doRenovate(Rumah rumahObj, TipeRenovasi tipeRenovasi) throws NotAbleToRenovasi {

	if (rumahObj instanceof RumahScandinavian && tipeRenovasi == VERTIKAL) {
			throw NotAbleToRenovasi();
	}

	if (rumahObj instanceof RumahSusun && (tipeRenovasi == VERTIKAL || tipeRenovasi == HORIZONTAL)) {
			throw NotAbleToRenovasi();
	}

	if (rumahObj instanceof RumahClassic && tipeRenovasi == VERTIKAL) {
			log.debug("Rumah Classic di renovasi vertikal");
	}

	if (rumahObj instanceof RumahClassic && tipeRenovasi == HORIZONTAL) {
			log.debug("Rumah Classic di renovasi horizontal");
	}

  rumahObj.renovasi();

  /* dst */
  /* code lanjutan buat yang lainnya */
}


Dan logicnya akan jalan.

Tetapi ada pertanyaan tambahan :

  • Bagaimana kalau nanti ada tambahan jenis rumah baru, seperti RumahArabian, atau RumahKampung, yang juga tidak boleh renovasi Vertikal ?
  • Akan banyak sekali kondisi If..then.. yang harus kita tambahkan kalau ada kasus baru lainnya.

Tentunya kita akan mengubah fungsi renovate diatas, dengan menambahkan tipe rumah di kondisi if diatas.

Dan itu melanggar konsep Open Closed Principle, yaitu kita mengubah lagi fungsi yang ada di dalam code diatas setiap kali ada penambahan class dengan tipe yang sama.



2. Memakai Marker Interface


Cara kedua adalah dengan memakai Marker Interface.

Kalau kita lihat dari code kasus diatas, maka yang kita butuhkan adalah Kategorisasi Renovasi Rumah untuk menentukan bahwa sebuah tipe Rumah bisa di renovasi sesuai pilihannya atau tidak.

Misalnya contohnya, kita buat 3 Marker Interface , sbb :


public interface Renovasi { }

public interface RenovasiVerticalable extends Renovasi {}

public interface RenovasiHorizontalable extends Renovasi {}


Lalu untuk tipe-tipe rumahnya, kita tambahkan Marker Interface nya, sbb :


public class RumahClassic implements Rumah, RenovasiHorizontalable, RenovasiVerticalable { // code }

public class RumahMinimalis implements Rumah, RenovasiHorizontalable, RenovasiVerticalable { // code }

public class RumahSkandinavian implements Rumah, RenovasiHorizontalable { // code }

public class RumahJapanese implements Rumah,  RenovasiHorizontalable { // code }

public class RumahSusun implements Rumah { // code }


Bisa kita lihat bahwa kita membawa kategori tipe renovasi ke level class/object.

Membawanya ke level abstraksi yang lebih tinggi.

Daripada dimasukkan sebagai enum TipeRenovasi


Dan di code renovasi nya kita ubah sbb :


----

public void doRenovate(Rumah rumah) throws NotAbleToRenovasi {

		if (!(rumah instanceof Renovasi)) {
			throw new NotAbleToRenovasi();
		}

		if (rumah instanceof RenovasiHorizontalable) {
			log.debug("Renovasi {} secara Horizontal", rumah.getClass().getSimpleName());
		}

		if (rumah instanceof RenovasiVerticalable) {
			log.debug("Renovasi {} secara Vertikal", rumah.getClass().getSimpleName());
		}

		rumah.renovate();
}


Nah sekarang kita bisa lihat kalau code kita menjadi lebih bersih, lebih abstrak dan berkutat di level object dan level yang lebih bersifat kategori, dibandingkan code sebelumnya yang terlalu masuk ke dalam implementasi class/object nya langsung.

Dengan cara diatas, maka kita akan lebih mudah menambahkan implementor dari rumah yang baru, misalnya RumahArabian atau RumahKampung tanpa perlu menambahkan kondisi khusus buat class implementornya tersebut.

Sekiaaan..