0Pricing
Go Academy · Pelajaran

Komposisi Interface dan Praktik Terbaik

Interface kecil dan inversi dependensi

Komposisi Interface dan Praktik Terbaik adalah pelajaran Go Academy gratis di CoddyKit. Ini adalah pelajaran 4 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Go Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Go Academy mencakup 4 pelajaran total.

Komposisi Antarmuka

Antarmuka Go dapat menyematkan antarmuka lain untuk menyusun antarmuka yang lebih besar:

package main
import "io"

// io.ReadWriter composes Reader and Writer
type ReadWriter interface {
    io.Reader
    io.Writer
}

// Your own composition:
type Processor interface {
    io.Reader
    Process() error
    io.Closer
}

func main() { _ = (*Processor)(nil) }

Prinsip Antarmuka Kecil

Antarmuka Go yang paling kuat memiliki satu atau dua metode. Hal ini memaksimalkan jumlah tipe yang dapat memenuhinya:

  • io.Reader — 1 metode
  • io.Writer — 1 metode
  • error — 1 metode
  • fmt.Stringer — 1 metode

Antarmuka besar lebih sulit dibuat tiruannya dan diuji.

Pembalikan Dependensi

Terimalah antarmuka dalam parameter fungsi, bukan tipe konkret. Hal ini memisahkan kode Anda dari implementasi tertentu:

package main
import "fmt"

type Store interface {
    Get(key string) (string, bool)
    Set(key, val string)
}

func cache(s Store, key, value string) {
    if _, ok := s.Get(key); !ok {
        s.Set(key, value)
    }
}

type MapStore struct{ m map[string]string }
func (ms *MapStore) Get(k string) (string, bool) { v, ok := ms.m[k]; return v, ok }
func (ms *MapStore) Set(k, v string) { ms.m[k] = v }

func main() {
    s := &MapStore{m: map[string]string{}}
    cache(s, "x", "hello")
    v, _ := s.Get("x")
    fmt.Println(v)
}

Pemisahan Antarmuka

Bagilah antarmuka besar menjadi antarmuka yang lebih kecil dan terfokus. Klien hanya bergantung pada metode yang mereka gunakan:

package main

// Bad: large interface forces all methods
type BigStorage interface {
    Read(key string) string
    Write(key, val string)
    Delete(key string)
    List() []string
    Backup() error
}

// Good: small, focused interfaces
type Reader interface{ Read(key string) string }
type Writer interface{ Write(key, val string) }
type Lister interface{ List() []string }

func readAll(r Reader) {} // only needs Read

func main() { _ = readAll }

Mengembalikan Tipe Konkret

Konstruktor sebaiknya mengembalikan tipe konkret, bukan antarmuka. Pemanggil selalu dapat menetapkan tipe konkret ke variabel antarmuka:

package main

type Logger interface{ Log(string) }
type ConsoleLogger struct{}
func (c *ConsoleLogger) Log(s string) {}

// Good: return concrete *ConsoleLogger
func NewConsoleLogger() *ConsoleLogger { return &ConsoleLogger{} }

// Avoid: return Logger (hides the concrete type)
// func NewConsoleLogger() Logger { return &ConsoleLogger{} }

func main() { _ = NewConsoleLogger() }

Antarmuka Berlebihan

Jangan membuat antarmuka untuk setiap tipe hanya sebagai berjaga-jaga. Buatlah antarmuka hanya ketika:

  • Anda memiliki beberapa implementasi sekarang atau dalam waktu dekat
  • Anda perlu membuat tiruan dependensi dalam pengujian
  • Anda sedang membangun pustaka dan ingin memisahkan pemanggil

Menyematkan Antarmuka untuk Ekstensi

Sematkan antarmuka untuk menambahkan metode opsional dengan nilai bawaan:

package main
import "fmt"

type Handler interface{ Handle(msg string) }
type NamedHandler interface {
    Handler
    Name() string
}

func dispatch(h Handler) {
    if nh, ok := h.(NamedHandler); ok {
        fmt.Printf("[%s] ", nh.Name())
    }
    h.Handle("event")
}

type MyHandler struct{}
func (m MyHandler) Handle(msg string)  { fmt.Println(msg) }
func (m MyHandler) Name() string       { return "my" }

func main() { dispatch(MyHandler{}) }

Membuat Tiruan dengan Antarmuka

Definisikan dependensi sebagai antarmuka; masukkan tiruan dalam pengujian:

package main
import "fmt"

type Clock interface{ Now() int64 }

type MockClock struct{ T int64 }
func (m MockClock) Now() int64 { return m.T }

func isExpired(c Clock, expiresAt int64) bool {
    return c.Now() > expiresAt
}

func main() {
    mc := MockClock{T: 1000}
    fmt.Println(isExpired(mc, 500))  // true
    fmt.Println(isExpired(mc, 1500)) // false
}

Penyematan Antarmuka vs Struct untuk Penggunaan Ulang

Gunakan penyematan antarmuka untuk komposisi API dan penyematan struct untuk penggunaan ulang kode. Keduanya memiliki tujuan yang berbeda dan tidak boleh disamakan.

Mendeteksi Kepatuhan Antarmuka pada Waktu Kompilasi

Gunakan pemeriksaan waktu kompilasi dengan pengenal kosong untuk memverifikasi bahwa tipe Anda memenuhi suatu antarmuka:

package main

type Doer interface{ Do() }
type MyType struct{}
func (m *MyType) Do() {}

// Compile-time check — no runtime cost
var _ Doer = (*MyType)(nil)

func main() {}

Pemeriksaan Singkat

Kapan Anda sebaiknya mendefinisikan antarmuka baru di Go?

Ringkasan: Praktik Terbaik Antarmuka

Hal-hal penting:

  • Jaga antarmuka tetap kecil — satu atau dua metode
  • Susun antarmuka dari antarmuka yang lebih kecil
  • Terima antarmuka, kembalikan tipe konkret
  • Buat antarmuka untuk kemudahan pengujian dan beberapa implementasi
  • Gunakan pemeriksaan waktu kompilasi dengan penugasan kosong

Instruksi Latihan

Rancang antarmuka Notifier dengan Notify(msg string) error. Implementasikan untuk EmailNotifier dan SMSNotifier. Tulislah fungsi broadcast yang mengirimkan ke []Notifier.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Komposisi Interface dan Praktik Terbaik” gratis?

Ya — teks lengkap “Komposisi Interface dan Praktik Terbaik” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Go Academy, upgrade ke CoddyKit PRO. Kursus Go Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Komposisi Interface dan Praktik Terbaik”?

Interface kecil dan inversi dependensi Kamu berlatih Go Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai Go Academy?

Tidak diperlukan pengalaman sebelumnya. Go Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 4 dari 4.

Berapa lama pelajaran “Komposisi Interface dan Praktik Terbaik” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran Go Academy ini?

Ya. Setiap pelajaran Go Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Mendefinisikan dan Mengimplementasikan Interface
  2. Interface Pustaka Standar Inti
  3. Asersi Tipe dan Switch Tipe
  4. Komposisi Interface dan Praktik Terbaik
← Kembali ke Go Academy