Arayüz Bileşimi
Coddy'nin GO Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 31 / 107.
Go, daha küçük arayüzleri birleştirerek daha büyük arayüzler inşa etmenize olanak tanır. Birçok metoda sahip tek bir büyük arayüz tanımlamak yerine, mevcut arayüzleri yeni bir arayüz tanımının içine gömersiniz.
type Reader interface {
Read() string
}
type Writer interface {
Write(data string)
}
// ReadWriter her iki arayüzü birleştirir
type ReadWriter interface {
Reader
Writer
}ReadWriter arayüzü artık hem Read() hem de Write() metotlarını gerektiriyor. Her iki metodu da uygulayan herhangi bir tür, ReadWriter arayüzünün yanı sıra ayrı ayrı Reader ve Writer arayüzlerini de karşılar.
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, ReadWriter arayüzünü sağlar
}Bu bileşim yaklaşımı, arayüzleri küçük ve odaklanmış tutar. İhtiyaca göre bunları karıştırıp eşleştirebilir, fonksiyonlarınız için kesin sözleşmeler oluşturabilirsiniz. Go'nun standart kütüphanesi, io.Reader ve io.Writer'ı birleştiren io.ReadWriter gibi bu deseni yaygın olarak kullanır.
Görev
KolayArayüz bileşimini gösteren bir medya oynatıcı sistemi oluşturalım. Küçük ve odaklanmış arayüzler oluşturacak, ardından bunları tek bir türün karşılayabileceği daha güçlü bir bileşik arayüzde birleştireceksin.
Kodunu iki dosyada düzenleyeceksin:
media.go: Üç arayüz ve bunların tümünü uygulayan bir yapı tanımla:Playermetoduna sahip birPlay() stringarayüzüRecordermetoduna sahip birRecord(content string) stringarayüzü- Hem
MediaDevicehem dePlayerarayüzlerini birleştiren birRecorderarayüzü - Bir
SmartDevicealanına sahip ve gerekli tüm metotları uygulayan birNameyapısı
main.go: AynıSmartDeviceyapısının farklı arayüz türleri üzerinden nasıl kullanılabileceğini gösteren işlevler oluştur:- Bir
UsePlayerkabul eden ve onunPlayermetodunu çağıranPlay - Bir
UseRecorderve bir içerik dizesi kabul eden, ardındanRecordermetodunu çağıranRecord - Bir
UseMediaDeviceve bir içerik dizesi kabul eden, ardından hemMediaDevicehem deRecordmetodunu çağıranPlay
SmartDeviceoluştur ve bunu üç arayüz türünün tümü üzerinden kullanmayı göster.- Bir
Aşağıdaki girdiler sağlanacaktır:
- 1. satır: Cihaz adı
- 2. satır: Kaydedilecek içerik
Metotların şu biçimlerde dizeler döndürmesi gerekir:
Play():[Name] is playingRecord(content):[Name] recorded: [content]
Örneğin, MyPhone ve voice memo verildiğinde çıktın şu şekilde olmalıdır:
MyPhone is playing
MyPhone recorded: voice memo
MyPhone recorded: voice memo
MyPhone is playingİlk iki satır, cihazın ayrı arayüzler (Player ve Recorder) üzerinden kullanıldığını gösterir. Son iki satır ise cihazın her iki yeteneği de gerektiren bileşik MediaDevice arayüzü üzerinden kullanıldığını gösterir. Tek bir SmartDevice yapısının, gerekli her iki metoda sahip olduğu için üç arayüzün tümünü karşıladığına dikkat et.
Kendin dene
package main
import (
"bufio"
"fmt"
"os"
)
// TODO: Bir Player kabul eden ve onun Play metodunu çağıran UsePlayer fonksiyonunu uygulayın
// Play() metodunun sonucunu yazdırmalıdır
// TODO: Bir Recorder ve bir içerik dizesi kabul eden UseRecorder fonksiyonunu uygulayın
// Record(content) metodunun sonucunu yazdırmalıdır
// TODO: Bir MediaDevice ve bir içerik dizesi kabul eden UseMediaDevice fonksiyonunu uygulayın
// Record(content) ve ardından Play() metodunun sonucunu yazdırmalıdır
func main() {
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
deviceName := scanner.Text()
scanner.Scan()
content := scanner.Text()
// TODO: Verilen isimle bir SmartDevice oluşturun
// TODO: Cihazı Player arayüzü üzerinden kullanın
// TODO: Cihazı Recorder arayüzü üzerinden kullanın
// TODO: Cihazı MediaDevice arayüzü üzerinden kullanın
_ = deviceName
_ = content
fmt.Println("Implement the solution")
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1Go OOP Temelleri
Harici DosyalarGo Çalışma Alanı ve ModüllerPaketler ve İçe AktarmalarDışa Aktarılan ve Aktarılmayan İsimlerGo'da OOP'ye GirişSınıf Olarak Struct'larStruct'larda Metot TanımlamaPointer ve Değer AlıcılarStruct BaşlatmaYapıcı FonksiyonlarÖzet - Basit Hesap Makinesi4Arayüzler
Arayüzlere GirişÖrtük UygulamaSözleşme Olarak ArayüzBoş Arayüz (any)Tür OnaylamaTür SeçimiArayüz BileşimiStringer ve Error ArayüzleriÖzet - Şekil Hesaplayıcı7Kapsülleme
Dışa Aktarılan ve Aktarılmayan AlanlarPaket Seviyesinde KapsüllemeGetter ve Setter MetotlarıGo'da Bilgi GizlemeÖzet - Öğrenci Kayıtları10Generics (Go 1.18+)
Generics'e GirişTür ParametreleriTür KısıtlamalarıGeneric Struct'larGeneric Metotlar İçin Geçici ÇözümÖzet - Generic Koleksiyon13Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişSingleton KalıbıFactory KalıbıAbstract Factory KalıbıObserver KalıbıStrategy Kalıbı2Türler ve Struct'lar: Derinlemesine İnceleme
Temel ve Bileşik TürlerÖzel Tür TanımlamalarıStruct EtiketleriAnonim Struct'larİç İçe Geçmiş Struct'larSıfır Değerler ve VarsayılanlarÖzet - Rehber5Kalıtım Yerine Kompozisyon
Go'da Neden Kalıtım YokStruct Gömme TemelleriMetot YükseltmeBirden Fazla Struct GömmeGömme vs AgregasyonGömülü Metotları GölgelemeÖzet - Çalışan Hiyerarşisi8Hata Yönetimi ve OOP
error ArayüzüÖzel Hata TürleriHata Sarmalama (fmt.Errorf)Sentinel Hatalarerrors.Is() ve errors.As()Panic, Defer ve RecoverÖzet - Dosya Ayrıştırıcı3İşaretçiler ve Bellek
Go'da İşaretçi TemelleriStruct İşaretçileriDeğer ile Geçme ve Referans ile Geçmenew() FonksiyonuGo'da Garbage CollectionÖzet - Linked List Oluşturucu6Go'da Polimorfizm
Interface'ler ile PolimorfizmGo'da Duck TypingInterface Karşılama KurallarıPolimorfik KoleksiyonlarDependency InjectionÖzet - Payment Processor9Eşzamanlılık ve OOP
Goroutine TemelleriKanallar ve İletişimTamponlu ve Tamponsuz KanallarSelect İfadesisync.Mutex ve sync.RWMutexsync.WaitGroupThread-Safe Struct TasarımıÖzet - Worker PoolKendi başına pratik yap: Online Go derleyicisi