Menu
Coddy logo textTech

Adaptör Kalıbı

Coddy'nin GO Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 92 / 107.

Adapter deseni, mevcut bir türü yeni bir arayüzle sarmalayarak uyumsuz arayüzlerin birlikte çalışmasını sağlar. Command eylemleri kapsüllerken, Adapter bir arayüzü istemcilerin beklediği başka bir arayüze dönüştürür.

Uygulamanızın beklediğinden farklı bir metot imzası kullanan eski bir yazıcınız olduğunu hayal edin:

// Uygulamanızın kullandığı hedef arayüz (interface)
type Printer interface {
    Print(text string) string
}

// Uyumsuz arayüze sahip eski yazıcı
type OldPrinter struct{}

func (o OldPrinter) PrintDocument(doc string, copies int) string {
    return fmt.Sprintf("Old printer: %s (x%d)", doc, copies)
}

Adaptör, eski türü sarmalar ve beklenen arayüzü uygular:

type OldPrinterAdapter struct {
    oldPrinter OldPrinter
}

func (a OldPrinterAdapter) Print(text string) string {
    return a.oldPrinter.PrintDocument(text, 1)
}

Artık eski yazıcı, Printer arayüzünü bekleyen kodlarla sorunsuz bir şekilde çalışır:

func PrintMessage(p Printer, msg string) string {
    return p.Print(msg)
}

adapter := OldPrinterAdapter{oldPrinter: OldPrinter{}}
result := PrintMessage(adapter, "Hello")  // "Old printer: Hello (x1)"

Adapter deseni; üçüncü taraf kütüphaneleri entegre ederken, eski kodlarla çalışırken veya arayüz gereksinimlerinize uymayan mevcut sınıfları kullanmanız gerektiğinde paha biçilemezdir. Orijinal kodu değiştirmeden bir köprü görevi görür.

challenge icon

Görev

Kolay

Adapter desenini kullanarak bir medya oynatıcı sistemi oluşturalım! Birleşik bir arayüz bekleyen modern bir ses oynatıcınız var, ancak tamamen farklı metot imzaları kullanan eski ses ekipmanlarını entegre etmeniz gerekiyor. Adaptörünüz bu boşluğu dolduracak ve eski donanımın yeni sistemle sorunsuz bir şekilde çalışmasını sağlayacaktır.

Kodunuzu üç dosya halinde düzenleyeceksiniz:

  • player.go: Hedef arayüzünüzü ve eski bir ses cihazını tanımlayın.

    Modern sisteminizin beklediği, bir parça adı alan ve bir oynatma mesajı döndüren Play(track string) string metoduna sahip bir AudioPlayer arayüzü oluşturun.

    Ayrıca bu arayüzle eşleşmeyen eski bir cihaz tanımlayın:

    • SpeedRPM alanına (int) sahip VinylPlayer yapısı — bu yapı, Playing [record] ([side] side) at [speed]rpm döndüren bir DropNeedle(record string, side string) string metoduna sahiptir.

    VinylPlayer'ın arayüzü AudioPlayer ile uyumsuzdur; iki parametre gerektirir ve tamamen farklı bir metot adı kullanır.

  • adapter.go: Eski cihazı uyumlu hale getiren adaptörünüzü oluşturun.

    Bir VinylPlayer nesnesini sarmalayan ve AudioPlayer arayüzünü uygulayan bir VinylAdapter yapısı oluşturun. Play çağrıldığında, adaptör plak çaların DropNeedle metodunu çağırmalı ve side parametresi için varsayılan olarak "A" değerini kullanmalıdır.

    Karşılaştırma için modern bir oynatıcı da oluşturun:

    • DigitalPlayer yapısı — Play metodu Streaming: [track] döndürür.
  • main.go: Her iki oynatıcının da aynı arayüz üzerinden çalıştığını gösterin.

    Müzik çalmak için arayüzü kullanan bir PlayMusic(player AudioPlayer, track string) string fonksiyonu oluşturun; bu fonksiyon dijital bir oynatıcı mı yoksa uyarlanmış bir plak çalar mı kullandığını bilmemeli veya umursamamalıdır.

    Bir oynatıcı türü ("digital" veya "vinyl") okuyun ve eğer vinyl ise RPM hızını da okuyun. Ardından parça adını okuyun. Uygun oynatıcıyı oluşturun (vinyl için adaptörü kullanarak), parçayı PlayMusic fonksiyonunuz aracılığıyla oynatın ve sonucu yazdırın.

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

  • Satır 1: Oynatıcı türü ("digital" veya "vinyl")
  • Satır 2: RPM hızı (sadece vinyl ise)
  • Son satır: Oynatılacak parça adı

Örneğin, şu girdi verildiğinde:

digital
Bohemian Rhapsody

Çıktınız şu olmalıdır:

Streaming: Bohemian Rhapsody

Ve şu girdi verildiğinde:

vinyl
33
Abbey Road

Çıktınız şu olmalıdır:

Playing Abbey Road (A side) at 33rpm

Ve şu girdi verildiğinde:

vinyl
45
Blue Monday

Çıktınız şu olmalıdır:

Playing Blue Monday (A side) at 45rpm

PlayMusic fonksiyonunun her iki oynatıcıyla da nasıl aynı şekilde çalıştığına dikkat edin; plak çaların aslında tamamen farklı bir arayüzden uyarlandığına dair hiçbir fikri yoktur. Adaptör, modern arayüz çağrılarını perde arkasında eski formata dönüştürür!

Kopya kağıdı

Adapter (Adaptör) deseni, mevcut bir türü yeni bir arayüzle sarmalayarak uyumsuz arayüzlerin birlikte çalışmasını sağlar.

Uygulamanızın beklediği bir hedef arayüz (interface) tanımlayın:

type Printer interface {
    Print(text string) string
}

Uyumsuz bir arayüzü olan eski (legacy) bir tür:

type OldPrinter struct{}

func (o OldPrinter) PrintDocument(doc string, copies int) string {
    return fmt.Sprintf("Old printer: %s (x%d)", doc, copies)
}

Eski türü sarmalayan ve hedef arayüzü uygulayan bir adaptör oluşturun:

type OldPrinterAdapter struct {
    oldPrinter OldPrinter
}

func (a OldPrinterAdapter) Print(text string) string {
    return a.oldPrinter.PrintDocument(text, 1)
}

Eski türün hedef arayüzü bekleyen kodla çalışmasını sağlamak için adaptörü kullanın:

func PrintMessage(p Printer, msg string) string {
    return p.Print(msg)
}

adapter := OldPrinterAdapter{oldPrinter: OldPrinter{}}
result := PrintMessage(adapter, "Hello")  // "Old printer: Hello (x1)"

Adapter deseni, üçüncü taraf kütüphaneleri entegre etmek, eski kodlarla çalışmak veya mevcut sınıfları orijinal kodu değiştirmeden gerekli arayüzlere uydurmak için kullanışlıdır.

Kendin dene

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

// PlayMusic, müzik çalmak için AudioPlayer arayüzünü kullanır
// Bu fonksiyon herhangi bir AudioPlayer uygulamasıyla çalışır
// TODO: player.Play(track) metodunu çağırmak ve sonucu döndürmek için bu fonksiyonu uygulayın
func PlayMusic(player AudioPlayer, track string) string {
	// TODO: Bu fonksiyonu uygulayın
	return ""
}

func main() {
	reader := bufio.NewReader(os.Stdin)
	
	// Oynatıcı türünü oku
	playerType, _ := reader.ReadString('\n')
	playerType = strings.TrimSpace(playerType)
	
	var player AudioPlayer
	var track string
	
	if playerType == "vinyl" {
		// Plak için RPM hızını oku
		rpmStr, _ := reader.ReadString('\n')
		rpmStr = strings.TrimSpace(rpmStr)
		rpm, _ := strconv.Atoi(rpmStr)
		
		// Parça adını oku
		track, _ = reader.ReadString('\n')
		track = strings.TrimSpace(track)
		
		// TODO: Verilen RPM ile bir VinylPlayer oluşturun
		// TODO: Bunu bir VinylAdapter içine sarın
		// TODO: player değişkenine atayın
		_ = rpm // rpm kullandığınızda bu satırı kaldırın
	} else {
		// Parça adını oku
		track, _ = reader.ReadString('\n')
		track = strings.TrimSpace(track)
		
		// TODO: Bir DigitalPlayer oluşturun
		// TODO: player değişkenine atayın
	}
	
	// TODO: PlayMusic fonksiyonunu çağırın ve sonucu yazdırın
	_ = player // player kullandığınızda bu satırı kaldırın
	_ = track  // track kullandığınızda bu satırı kaldırın
}
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