Menu
Coddy logo textTech

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.

challenge icon

Görev

Kolay

Arayüz bileşimini (interface composition) gösteren bir medya oynatıcı sistemi oluşturalım. Küçük, odaklanmış arayüzler oluşturacak ve ardından bunları tek bir türün karşılayabileceği daha güçlü, birleşik bir arayüzde birleştireceksiniz.

Kodunuzu iki dosya halinde düzenleyeceksiniz:

  • media.go: Üç arayüz ve bunların hepsini uygulayan bir struct tanımlayın:
    • Play() string metoduna sahip bir Player arayüzü
    • Record(content string) string metoduna sahip bir Recorder arayüzü
    • Hem Player hem de Recorder arayüzlerini birleştiren bir MediaDevice arayüzü
    • Gerekli tüm metodları uygulayan, Name alanına sahip bir SmartDevice struct'ı
  • main.go: Aynı SmartDevice yapısının farklı arayüz türleri üzerinden nasıl kullanılabileceğini gösteren fonksiyonlar oluşturun. Üç fonksiyon yazın:
    • Bir Player kabul eden ve onun Play metodunu çağıran UsePlayer
    • Bir Recorder ve bir içerik dizesi kabul eden, ardından Record metodunu çağıran UseRecorder
    • Bir MediaDevice ve bir içerik dizesi kabul eden, ardından hem Record hem de Play metodlarını çağıran UseMediaDevice
    Girdiden cihaz adını ve içeriği okuyun, bir SmartDevice oluşturun ve onu her üç arayüz türü üzerinden kullanmayı gösterin.

Aşağıdaki girdiler sağlanacaktır:

  • Satır 1: Cihaz adı
  • Satır 2: Kaydedilecek içerik

Metodlarınız şu formatlarda dizeler döndürmelidir:

  • Play(): [Name] is playing
  • Record(content): [Name] recorded: [content]

Örneğin, MyPhone ve voice memo verildiğinde, çıktınız ş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 bireysel arayüzler (Player ve Recorder) aracılığıyla kullanımını gösterir. Son iki satır ise her iki yeteneği de gerektiren birleşik MediaDevice arayüzü aracılığıyla kullanımını gösterir. Tek bir SmartDevice yapısının, gerekli her iki metoda da sahip olduğu için her üç arayüzü de nasıl karşıladığına dikkat edin.

Kopya kağıdı

Go, mevcut arayüzleri yeni bir arayüz tanımı içine gömerek daha küçük olanları birleştirerek (composing) daha büyük arayüzler oluşturmanıza olanak tanır:

type Reader interface {
    Read() string
}

type Writer interface {
    Write(data string)
}

// ReadWriter her iki arayüzü birleştirir
type ReadWriter interface {
    Reader
    Writer
}

Gömülü arayüzlerdeki tüm metotları uygulayan herhangi bir tür, birleştirilmiş arayüzü 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ü karşılar
}

Birleştirilmiş bir arayüzü uygulayan bir tür, aynı zamanda gömülü olan her bir arayüzü de karşılar. Bu birleştirme yaklaşımı, arayüzleri küçük ve odaklanmış tutarken fonksiyonlarınız için kesin sözleşmeler oluşturmanıza olanak tanır.

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")
}
quiz iconKendini test et

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