Apps Artificial Intelligence CSS DevOps Go JavaScript Laravel Linux MongoDB MySQL PHP Python Rust Vue

Belajar Interface di Go: Konsep, Contoh, dan Best Practice

2 min read .
Belajar Interface di Go: Konsep, Contoh, dan Best Practice

Kalau baru kenal Go, biasanya saya cepat ketemu dengan konsep interface.
Awalnya mungkin agak membingungkan: apa bedanya sama struct biasa? Kenapa harus pakai interface?

Singkatnya, interface di Go itu kontrak. Ia bilang: “kalau kamu mau disebut tipe ini, kamu harus punya metode A, B, C.”
Yang keren, di Go saya nggak perlu deklarasi eksplisit kalau sebuah struct implements interface—cukup dengan punya metode yang sesuai, struct itu otomatis memenuhi interface.

Apa Itu Interface?

Interface di Go pada dasarnya cuma daftar metode. Contoh simpel:

type Speaker interface {
    Speak() string
}

type Person struct {
    Name string
}

func (p Person) Speak() string {
    return "Hello, my name is " + p.Name
}

Karena Person punya metode Speak, otomatis dia dianggap sebagai Speaker. Jadi saya bisa pakai:

var s Speaker
s = Person{Name: "Alice"}
fmt.Println(s.Speak()) // Hello, my name is Alice

Kenapa Repot-Repot Pakai Interface?

Beberapa alasan kenapa interface itu berguna banget:

  • Loose coupling → kode jadi nggak bergantung ke implementasi spesifik.
  • Fleksibel → gampang ganti-ganti implementasi tanpa ubah banyak hal.
  • Testing lebih gampang → bisa bikin mock dari interface buat unit test.

Contoh Kasus: Notifikasi

Bayangkan kita mau bikin sistem notifikasi, bisa via email atau SMS.

type Notifier interface {
    Notify() string
}

type Email struct{ Address string }
func (e Email) Notify() string { return "Sending email to " + e.Address }

type SMS struct{ Number string }
func (s SMS) Notify() string { return "Sending SMS to " + s.Number }

Sekarang, kita bisa pakai Notifier tanpa peduli implementasinya:

var n Notifier

n = Email{Address: "example@example.com"}
fmt.Println(n.Notify())

n = SMS{Number: "123-456-7890"}
fmt.Println(n.Notify())

Tanpa Interface vs Dengan Interface

Bayangin kita punya fungsi buat kirim notifikasi. Kalau tanpa interface, kodenya bisa jadi kayak gini:

func SendEmail(e Email) {
    fmt.Println(e.Notify())
}

func SendSMS(s SMS) {
    fmt.Println(s.Notify())
}

func main() {
    SendEmail(Email{Address: "example@example.com"})
    SendSMS(SMS{Number: "123-456-7890"})
}

Masalahnya: tiap tipe baru (misalnya WhatsApp, Push Notification), kita harus bikin fungsi lagi. Ribet.

Sekarang coba pakai interface:

func SendNotification(n Notifier) {
    fmt.Println(n.Notify())
}

func main() {
    SendNotification(Email{Address: "example@example.com"})
    SendNotification(SMS{Number: "123-456-7890"})
}

Lebih rapi, fleksibel, dan gampang ditambahin implementasi baru. Cukup bikin struct dengan Notify(), otomatis bisa dipakai di SendNotification.

Interface Bisa Dikombinasi

Go juga ngizinin interface dikomposisi jadi yang lebih kompleks:

type Reader interface {
    Read() string
}

type Writer interface {
    Write() string
}

type ReadWriter interface {
    Reader
    Writer
}

Kalau ada struct File yang punya metode Read dan Write, otomatis dia memenuhi ReadWriter.

Interface Kosong

Satu hal yang sering bikin bingung: interface{} alias interface kosong. Artinya? Bisa menampung nilai tipe apa aja.

func printValue(v interface{}) {
    fmt.Println(v)
}

func main() {
    printValue(42)
    printValue("Hello")
    printValue(3.14)
}

Gunanya oke buat data generik, tapi jangan kebablasan pakai, soalnya hilang type safety.

Best Practice

  • Bikin interface kecil dan fokus → misalnya cuma 1–2 metode.
  • Tulis kode berdasarkan interface, bukan implementasi konkrit.
  • Jangan kebanyakan pakai interface{} kalau nggak benar-benar perlu.

Penutup

Interface adalah salah satu fitur paling penting di Go. Begitu paham konsep dasarnya—bahwa dia cuma kontrak metode—hidup jadi lebih mudah. Entah mau bikin kode fleksibel, lebih gampang dites, atau lebih modular, interface akan selalu jadi senjata andalan.

Lihat Juga

chevron-up