author-pic

Ferry S

An ISTJ, Type 5, Engineer, Gamer, and Thriller-Movies-Lover
Kenapa Harus Enum?
Sat. Mar 11th, 2023 01:31 PM4 mins read
Kenapa Harus Enum?
Source: Bing Image Creator - enums

Enum atau Enumeration adalah object khusus pada pemrograman yang berisi value constant yang bisa di-reuse di berbagai tempat. Enum atau Constant dapat membuat code jadi lebih mudah dibaca dan dimaintain. Penulisan Enum value menurut convention biasanya ditulis menggunakan format “SNAKE_UPPERCASE”. Kali ini gw akan bahas tentang apa aja manfaat menggunakan Enum dan kenapa harus Enum dibanding pakai value biasa. Seperti biasa gw akan pakai Java sebagai contoh, tapi Enum itu ga hanya sebatas Java aja, di Python, Typescript, C#, dan beberapa bahasa pemrograman lain juga ada. Yang penting paham fitur yang ditawarkan😊. Berikut adalah alasan mengapa kita harus pakai Enum:

Alasan paling kuat mengapa kita harus pakai Enum adalah untuk mengurangi resiko kecerobohan saat ngoding, terutama ketika menggunakan value constant yang sering digunakan di berbagai tempat. Contohnya seperti ini:

Class Order

@Data
public class Order{
	String orderNo;
	String status;
}

Update Order

void confirmOrder(){
	Order order = getOrder();
	if(!order.getStatus().equals("created")){
		throw new IllegalArgumentException("can not confirm order");
	}
	order.setStatus("confirmed");
}

void createOrder(){
	Order order = getOrder();
	order.setStatus("created");
}

Pada code di atas, ketika order tersebut dibuat, statusnya di-set “created”. Ketika ordernya dikonfirmasi statusnya dicek dulu, apakah “created” atau bukan. Kalau bukan, maka akan error. Kalau “created” maka statusnya akan diubah jadi “confirmed”. Statusnya menggunakan tipe data String. Masalahnya adalah bisa saja terjadi typo saat menulis “created” ketika validasi confirmation sehingga yang tertulis adalah “creatd”. Tentu saja itu berakibat fatal dan menghasilkan bugs. Saat code dijalankan tentu tidak akan compile error karena penggunaan tipe datanya tidak salah. Kecerobohan seperti ini bisa terjadi pada siapapun. Sekarang kita ganti Status Order tersebut pakai Enum:

Enum Status Order

public enum OrderStatus{
	CREATED,
	CONFIRMED,
	;
}

Class Order

@Data
public class Order{
	String orderNo;
	OrderStatus status;
}

Update Order

void confirmOrder(){
	Order order = getOrder();
	if(order.getStatus() != OrderStatus.CREATED){
		throw new IllegalArgumentException("can not confirm order");
	}
	order.setStatus(OrderStatus.CONFIRMED);
}

void createOrder(){
	Order order = getOrder();
	order.setStatus(OrderStatus.CREATED);
}

Sekarang dengan menggunakan Enum kita akan “dipaksa” untuk menginput value yang sama persis sesuai Enum value. Misalkan kalau masih terjadi typo saat mengetik “CREATED” menjadi “CREATD”, maka akan compile error sehingga kecerobohan tersebut bisa didekteksi lebih dini. Bahkan dari IDE pun pasti akan muncul tanda bahwa ada yang error di code. Valuenya jadi Type-safe karena kita ga mungkin bisa input value lain selain value yang tertulis pada Enum.

Pada contoh sebelumnya, kita menggunakan Enum langsung pada Status Ordernya. Sekarang gimana kalau statusnya menggunakan status code seperti ini:

Class Order

@Data
public class Order{
	String orderNo;
	int statusCode;
}

Update Order

void confirmOrder(){
	Order order = getOrder();
	if(order.getStatusCode() != 1){
		throw new IllegalArgumentException("can not confirm order");
	}
	order.setStatusCode(2);
}

void createOrder(){
	Order order = getOrder();
	order.setStatusCode(1);
}

Pada code di atas ketika order tersebut dibuat, statusnya di-set 1. Ketika ordernya dikonfirmasi oleh seller, statusnya di-set 2. Code tersebut ga readable karena membuat kita harus menghafal semua status code dari order. Biar lebih gampang diingat, kita bisa membuat Enum untuk order status seperti ini:

Enum Order Status

@RequiredArgsConstructor
public enum OrderStatus{
	CREATED(1),
	CONFIRMED(2),
	;

	public final int statusCode;
}

Update Order

void confirmOrder(){
	Order order = getOrder();
	if(order.getStatusCode() != OrderStatus.CREATED.statusCode){
		throw new IllegalArgumentException("can not confirm order");
	}
	order.setStatusCode(OrderStatus.CONFIRMED.statusCode);
}

void createOrder(){
	Order order = getOrder();
	order.setStatusCode(OrderStatus.CREATED.statusCode);
}

Sekarang kita ga perlu mengingat masing-masing angka pada status order. Cukup gunakan code yang udah ditulis pada Enum. Istilah kata, code tersebut “self-documented” karena kita tidak perlu bikin dokumentasi di code untuk menunjukkan bahwa “created” itu 1, atau “confirmed” itu 2.

Enum juga membuat code jadi lebih maintainable. Misalnya untuk status "created" tadinya status codenya adalah 1 dan itu udah dipakai di berbagai tempat. Kalau ada perubahan status code, itu artinya kita harus mengganti semua status code pada code yang masih menggunakan status code 1.

Class Order

@Data
public class Order{
	String orderNo;
	int statusCode;
}

Update Order

void confirmOrder(){
	Order order = getOrder();
	if(order.getStatusCode() != 1){
		throw new IllegalArgumentException("can not confirm order");
	}
	order.setStatusCode(2);
}

void createOrder(){
	Order order = getOrder();
	order.setStatusCode(1);
}

Misalkan seiring perjalanan waktu, status code untuk "created" akan di-refactor menjadi 0. Pasti bakal repot mengubah semua code terkait karena harus diganti semua satu-persatuđŸ˜”. Belum lagi kalau misalkan selain status code, juga ada penambahan status description. Makin repot dong. Maintainance akan lebih mudah jika kita menggunakan Enum, kita bisa mengganti status code maupun menambah status description seperti ini:

Enum Status Order

@RequiredArgsConstructor
public enum OrderStatus{
	CREATED(1, "create by user"),
	CONFIRMED(2, "order is confirmed by seller"),
	;

	public final int statusCode;
	public final String description;
}

Class Order

@Data
public class Order{
	String orderNo;
	OrderStatus status;
}

Update Order

void confirmOrder(){
	Order order = getOrder();
	if(order.getStatus() != OrderStatus.CREATED){
		throw new IllegalArgumentException("can not confirm order");
	}
	order.setStatus(OrderStatus.CONFIRMED);

	//check status code & description
	System.out.println("status code = " + order.getStatus().statusCode);
	System.out.println("description = " + order.getStatus().description);
}

void createOrder(){
	Order order = getOrder();
	order.setStatus(OrderStatus.CREATED);

	//check status code & description
	System.out.println("status code = " + order.getStatus().statusCode);
	System.out.println("description = " + order.getStatus().description);
}

Jika suatu saat terjadi perubahan status code, kita hanya perlu mengubah status code pada Enum saja. Misalnya status code "CREATED" yang tadinya 1 diganti jadi 0, maka cukup ubah value status code pada Enum OrderStatus. Code tetap konsisten meskipun ada perubahan tanpa banyak refactor, karena valuenya akan otomatis mengikuti value constant dari Enum tersebut.

Itulah beberapa alasan mengapa kita harus pakai Enum. Dari sisi performa tentu aja ada sedikit impact, tapi tenang saja karena Enum itu dibaca sekali saja saat class loading, bukan tiap runtime. Itu pun impactnya cuma sekian nanosecond, ga ada yang peduli. Kalaupun sekian nanosecond itu sangat penting, maka pakai bahasa C atau Assembly sekalian yang cocok untuk develop program yang sangat cepat. Menggunakan Enum membuat code kita jadi lebih maintainable dan gampang dibaca. Code jadi lebih konsisten ketika terjadi perubahan value dan proses refactor akan lebih mudah. Ketika kita salah menginput value Enum, IDE pasti akan ngasih tau kalau ada error sehingga bugs typo lebih cepat dideteksi. Btw, pronunciation Enum ada bermacam-macam. Ada yang menyebutnya "inam" (dalam bahasa inggris seperti menyebut huruf "e" dan "numb"), ada juga yang menyebut "inum" (dalam bahasa inggris seperti menyebut huruf "e" dan "noom"), atau bisa juga dibaca "enum" (seperti pelafalan indonesia). Di youtube juga orang-orang nyebutinnya beda-beda. Sebenarnya ga ada pronunciation resminya sih, jadi bebas-bebas aja nyebutnya😅.