Komposisi Interface
Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan GO di Coddy. Pelajaran 31 dari 107.
Go memungkinkan kamu membangun interface yang lebih besar dengan menggabungkan interface yang lebih kecil. Alih-alih mendefinisikan satu interface besar dengan banyak method, kamu menyematkan interface yang sudah ada ke dalam definisi interface baru.
type Reader interface {
Read() string
}
type Writer interface {
Write(data string)
}
// ReadWriter menggabungkan kedua interface
type ReadWriter interface {
Reader
Writer
}Interface ReadWriter kini mensyaratkan method Read() dan Write(). Tipe apa pun yang mengimplementasikan kedua method tersebut memenuhi ReadWriter, serta Reader dan Writer secara terpisah.
type File struct {
Name string
}
func (f File) Read() string { return "file content" }
func (f File) Write(data string) { fmt.Println("Writing:", data) }
func Process(rw ReadWriter) {
content := rw.Read()
rw.Write(content)
}
func main() {
f := File{Name: "data.txt"}
Process(f) // File memenuhi antarmuka ReadWriter
}Pendekatan komposisi ini menjaga antarmuka tetap kecil dan terfokus. Kamu bisa menggabungkan antarmuka sesuai kebutuhan untuk membuat kontrak yang tepat bagi fungsi-fungsimu. Pustaka standar Go banyak menggunakan pola ini, seperti io.ReadWriter yang menggabungkan io.Reader dan io.Writer.
Tantangan
MudahMari kita buat sistem pemutar media yang menunjukkan komposisi interface. Kamu akan membuat interface kecil dengan fokus tertentu, lalu menggabungkannya menjadi interface gabungan yang lebih andal dan dapat dipenuhi oleh satu tipe.
Kamu akan mengatur kodemu dalam dua file:
media.go: Definisikan tiga interface dan sebuah struct yang mengimplementasikan semuanya:- Interface
Playerdengan methodPlay() string - Interface
Recorderdengan methodRecord(content string) string - Interface
MediaDeviceyang menggabungkanPlayerdanRecorder - Struct
SmartDevicedengan fieldNameyang mengimplementasikan semua method yang diperlukan
- Interface
main.go: Buat fungsi yang menunjukkan cara menggunakanSmartDeviceyang sama melalui tipe interface yang berbeda. Tulis tiga fungsi:UsePlayeryang menerimaPlayerdan memanggil methodPlay-nyaUseRecorderyang menerimaRecorderdan string konten, lalu memanggilRecordUseMediaDeviceyang menerimaMediaDevicedan string konten, lalu memanggilRecorddanPlay
SmartDevice, lalu tunjukkan cara menggunakannya melalui ketiga tipe interface.
Input berikut akan diberikan:
- Baris 1: Nama perangkat
- Baris 2: Konten yang akan direkam
Method-mu harus mengembalikan string dalam format berikut:
Play():[Name] is playingRecord(content):[Name] recorded: [content]
Misalnya, jika diberikan MyPhone dan voice memo, output-mu seharusnya:
MyPhone is playing
MyPhone recorded: voice memo
MyPhone recorded: voice memo
MyPhone is playingDua baris pertama menunjukkan perangkat yang digunakan melalui interface masing-masing (Player dan Recorder). Dua baris terakhir menunjukkan perangkat yang digunakan melalui interface gabungan MediaDevice, yang memerlukan kedua kemampuan tersebut. Perhatikan bahwa satu SmartDevice milikmu memenuhi ketiga interface karena memiliki kedua method yang diperlukan.
Coba sendiri
package main
import (
"bufio"
"fmt"
"os"
)
// TODO: Implementasikan UsePlayer yang menerima Player dan memanggil method Play-nya
// Fungsi ini harus mencetak hasil Play()
// TODO: Implementasikan UseRecorder yang menerima Recorder dan string content
// Fungsi ini harus mencetak hasil Record(content)
// TODO: Implementasikan UseMediaDevice yang menerima MediaDevice dan string content
// Fungsi ini harus mencetak hasil Record(content), lalu Play()
func main() {
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
deviceName := scanner.Text()
scanner.Scan()
content := scanner.Text()
// TODO: Buat SmartDevice dengan nama yang diberikan
// TODO: Gunakan perangkat melalui interface Player
// TODO: Gunakan perangkat melalui interface Recorder
// TODO: Gunakan perangkat melalui interface MediaDevice
_ = deviceName
_ = content
fmt.Println("Implement the solution")
}
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Objek
1Dasar-Dasar OOP di Go
File EksternalWorkspace Go dan modulePaket dan ImporNama yang Diekspor dan Tidak DieksporPengantar OOP di Gostruct sebagai classMendefinisikan method pada structPointer receiver vs value receiverInisialisasi structFungsi KonstruktorUlasan: Kalkulator Sederhana4Interface
Pengenalan InterfaceImplementasi ImplisitInterface sebagai KontrakInterface Kosong (any)Type AssertionType SwitchKomposisi InterfaceInterface Stringer & ErrorUlasan: Kalkulator Bentuk7Enkapsulasi
Field yang Diekspor vs Tidak DieksporEnkapsulasi Tingkat PackageMethod Getter dan SetterPenyembunyian Informasi di GoRingkasan: Data Siswa10Generics (Go 1.18+)
Pengantar GenericsParameter TipeBatasan TipeStruct GenerikCara Alternatif untuk Method GenerikRingkasan Koleksi Generik2Mendalami Tipe dan Struct
Tipe Dasar dan KompositDefinisi Tipe KustomTag StructStruct AnonimStruct BersarangNilai Nol dan Nilai BawaanRangkuman: Buku Kontak5Komposisi daripada Pewarisan
Mengapa Go Tidak Memiliki PewarisanDasar Penyematan StructPromosi methodMenyematkan Beberapa StructPenyematan vs AgregasiMembayangi method yang DisematkanRangkuman: Hierarki Karyawan8Penanganan Error & OOP
Interface errorTipe Error KustomPembungkusan Error (fmt.Errorf)Error Sentinelerrors.Is() dan errors.As()Panic, Defer, dan RecoverRangkuman: Parser File3Pointer dan Memori
Dasar-Dasar Pointer di GoPointer ke StructPass by Value vs ReferenceFungsi new()Garbage Collection di GoRekap: Pembuat Linked List6Polimorfisme di Go
Polimorfisme melalui InterfaceDuck Typing di GoAturan Pemenuhan InterfaceKoleksi PolimorfikInjeksi DependensiRangkuman: Pemroses Pembayaran9Konkruensi & OOP
Dasar-dasar GoroutineChannel & KomunikasiChannel Ber-buffer vs Tanpa BufferPernyataan selectsync.Mutex & sync.RWMutexsync.WaitGroupDesain Struct yang Aman untuk ThreadRingkasan: Worker PoolLatihan sendiri: Compiler Go online