Menu
CoddyTech

Interface sebagai Kontrak

Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan GO di Coddy. Pelajaran 27 dari 107.

Menganggap interface sebagai kontrak membantumu merancang program Go yang lebih baik. Saat sebuah fungsi menerima tipe interface, maksudnya: "Aku tidak peduli tipe konkret apa yang kamu berikan, selama tipe itu memenuhi kontrak ini."

Pemikiran berbasis kontrak ini memungkinkan kamu menulis fungsi yang berfokus pada perilaku, bukan tipe tertentu. Pertimbangkan fungsi yang perlu memproses data dari berbagai sumber:

type DataSource interface {
    FetchData() string
}

func ProcessData(src DataSource) {
    data := src.FetchData()
    fmt.Println("Processing:", data)
}

Fungsi ProcessData tidak tahu atau peduli apakah menerima koneksi database, client API, atau pembaca file. Fungsi ini hanya membutuhkan input yang bisa FetchData(). Tipe apa pun yang memenuhi kontrak ini bisa digunakan.

type Database struct{ ConnectionString string }
func (d Database) FetchData() string { return "data from DB" }

type APIClient struct{ Endpoint string }
func (a APIClient) FetchData() string { return "data from API" }

func main() {
    db := Database{ConnectionString: "localhost"}
    api := APIClient{Endpoint: "https://api.example.com"}
    
    ProcessData(db)   // Berhasil!
    ProcessData(api)  // Ini juga berhasil!
}

Pendekatan kontrak ini juga membuat kodemu lebih mudah diuji. Saat pengujian, kamu bisa membuat tipe mock yang memenuhi interface tanpa memerlukan database atau koneksi jaringan sungguhan. Fungsi yang diuji tidak mengetahui perbedaannya karena kontrak tersebut terpenuhi.

challenge icon

Tantangan

Mudah

Mari kita buat sistem notifikasi yang menunjukkan cara interface berfungsi sebagai kontrak. Kamu akan membuat interface Notifier yang mendefinisikan arti mengirim notifikasi, lalu mengimplementasikan beberapa saluran notifikasi yang semuanya mematuhi kontrak ini.

Kamu akan menyusun kodemu dalam dua file:

  • notifiers.go: Definisikan interface Notifier dengan satu method Notify(message string) string. Lalu buat tiga struct berbeda yang memenuhi kontrak ini:
    • ConsoleNotifier dengan field Prefix
    • FileNotifier dengan field Filename
    • WebhookNotifier dengan field URL
    Setiap struct harus mengimplementasikan method Notify untuk mengembalikan string yang menjelaskan cara notifikasi akan dikirim.
  • main.go: Buat fungsi bernama BroadcastAlert yang menerima slice berisi nilai Notifier dan string pesan. Fungsi ini harus memanggil Notify pada setiap notifier dan mencetak hasilnya. Baca konfigurasi dari input, buat ketiga tipe notifier, lalu sebarkan peringatan melalui semuanya.

Input berikut akan diberikan:

  • Baris 1: Prefiks console
  • Baris 2: Nama file
  • Baris 3: URL webhook
  • Baris 4: Pesan peringatan

Method Notify-mu harus mengembalikan string dengan format berikut:

  • ConsoleNotifier: [Prefix] [message]
  • FileNotifier: Writing to [Filename]: [message]
  • WebhookNotifier: POST [URL]: [message]

Misalnya, jika inputnya adalah ALERT:, log.txt, https://hooks.example.com, dan Server down!, output-mu seharusnya:

ALERT: Server down!
Writing to log.txt: Server down!
POST https://hooks.example.com: Server down!

Keunggulan desain ini adalah fungsi BroadcastAlert-mu tidak mengetahui atau memedulikan tipe notifier tertentu. Fungsi ini hanya membutuhkan setiap notifier untuk memenuhi kontrak Notifier. Kamu dapat menambahkan SlackNotifier atau EmailNotifier nanti tanpa mengubah fungsi penyebaran sama sekali.

Coba sendiri

package main

import (
	"bufio"
	"fmt"
	"os"
)

// BroadcastAlert mengirim pesan melalui semua notifier
// TODO: Implementasikan fungsi ini untuk:
// - Menerima slice berisi nilai Notifier dan string pesan
// - Memanggil Notify pada setiap notifier dan mencetak hasilnya
func BroadcastAlert(notifiers []Notifier, message string) {
	// TODO: Lakukan perulangan pada notifiers dan cetak setiap hasil notifikasi
}

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	
	// Baca prefiks konsol
	scanner.Scan()
	prefix := scanner.Text()
	
	// Baca nama file
	scanner.Scan()
	filename := scanner.Text()
	
	// Baca URL webhook
	scanner.Scan()
	url := scanner.Text()
	
	// Baca pesan peringatan
	scanner.Scan()
	message := scanner.Text()
	
	// TODO: Buat instance dari ketiga tipe notifier
	// - ConsoleNotifier dengan prefiks
	// - FileNotifier dengan nama file
	// - WebhookNotifier dengan URL
	
	// TODO: Buat slice berisi nilai Notifier untuk ketiga notifier
	
	// TODO: Panggil BroadcastAlert dengan notifiers dan message
	
	_ = prefix
	_ = filename
	_ = url
	_ = message
	fmt.Println("TODO: Implement the solution")
}
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Objek

Latihan sendiri: Compiler Go online