Menu
Coddy logo textTech

Sözleşme Olarak Arayüz

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

Arayüzleri sözleşmeler olarak düşünmek, daha iyi Go programları tasarlamanıza yardımcı olur. Bir işlev bir arayüz türünü kabul ettiğinde şunu söylemiş olur: "Bana hangi somut türü verdiğiniz umurumda değil, yeter ki bu sözleşmeyi yerine getirsin."

Sözleşme tabanlı bu düşünme biçimi, belirli türler yerine davranışa odaklanan işlevler yazmanı sağlar. Çeşitli kaynaklardan gelen verileri işlemesi gereken bir işlevi ele alalım:

type DataSource interface {
    FetchData() string
}

func ProcessData(src DataSource) {
    data := src.FetchData()
    fmt.Println("Processing:", data)
}

ProcessData işlevi, bir veritabanı bağlantısı, bir API istemcisi veya bir dosya okuyucusu alıp almadığını bilmez ve bunu önemsemez. Yalnızca girdinin FetchData() işlemini gerçekleştirebilmesini gerektirir. Bu sözleşmeye uyan her tür işe yarar.

type Database struct{ ConnectionString string }
func (d Database) FetchData() string { return "data from DB" }

type APIClient struct{ Endpoint string }
func (a APIClient) FetchData() string { return "data from API" }

func main() {
    db := Database{ConnectionString: "localhost"}
    api := APIClient{Endpoint: "https://api.example.com"}
    
    ProcessData(db)   // Çalışıyor!
    ProcessData(api)  // Bu da çalışıyor!
}

Bu sözleşme yaklaşımı kodunuzu daha test edilebilir hâle de getirir. Test sırasında gerçek veritabanlarına veya ağ bağlantılarına ihtiyaç duymadan arayüzü karşılayan bir sahte tür oluşturabilirsiniz. Test edilen işlev, sözleşme yerine getirildiği için aradaki farkı bilmez.

challenge icon

Görev

Kolay

Arayüzlerin sözleşme olarak nasıl davrandığını gösteren bir bildirim sistemi oluşturalım. Bildirim göndermenin ne anlama geldiğini tanımlayan bir Notifier arayüzü oluşturacak, ardından bu sözleşmeye uyan birden çok bildirim kanalını uygulayacaksın.

Kodunu iki dosyaya ayıracaksın:

  • notifiers.go: Tek bir Notifier yöntemine sahip bir Notify(message string) string arayüzü tanımla. Ardından bu sözleşmeyi karşılayan üç farklı yapı oluştur:
    • ConsoleNotifier, bir Prefix alanıyla
    • FileNotifier, bir Filename alanıyla
    • WebhookNotifier, bir URL alanıyla
    Her yapı, bildirimin nasıl gönderileceğini açıklayan bir dize döndürmek üzere Notify yöntemini uygulamalıdır.
  • main.go: Bir BroadcastAlert değerleri dilimini ve bir mesaj dizesini kabul eden Notifier adlı bir işlev oluştur. Bu işlev, her bildirimci için Notify yöntemini çağırmalı ve sonuçları yazdırmalıdır. Yapılandırmayı girdiden oku, üç bildirimci türünün tümünü oluştur ve bir uyarıyı hepsi üzerinden yayınla.

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

  • 1. satır: Konsol öneki
  • 2. satır: Dosya adı
  • 3. satır: Webhook URL'si
  • 4. satır: Uyarı mesajı

Notify yöntemlerin şu biçimlerde dizeler döndürmelidir:

  • ConsoleNotifier: [Prefix] [message]
  • FileNotifier: Writing to [Filename]: [message]
  • WebhookNotifier: POST [URL]: [message]

Örneğin ALERT:, log.txt, https://hooks.example.com ve Server down! verildiğinde çıktın şu şekilde olmalıdır:

ALERT: Server down!
Writing to log.txt: Server down!
POST https://hooks.example.com: Server down!

Bu tasarımın gücü, BroadcastAlert işlevinin belirli bildirimci türlerini bilmemesi veya önemsememesidir. Yalnızca her birinin Notifier sözleşmesini yerine getirmesini gerektirir. Daha sonra yayın işlevini hiç değiştirmeden bir SlackNotifier veya EmailNotifier ekleyebilirsin.

Kendin dene

package main

import (
	"bufio"
	"fmt"
	"os"
)

// BroadcastAlert tüm notifiers aracılığıyla bir mesaj gönderir
// TODO: Bu fonksiyonu şunları yapacak şekilde uygula:
// - Notifier değerlerinden bir dilim ve bir mesaj dizesi kabul et
// - Her notifier üzerinde Notify çağır ve sonuçları yazdır
func BroadcastAlert(notifiers []Notifier, message string) {
	// TODO: notifiers üzerinde döngü yap ve her bildirim sonucunu yazdır
}

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	
	// Konsol önekini oku
	scanner.Scan()
	prefix := scanner.Text()
	
	// Dosya adını oku
	scanner.Scan()
	filename := scanner.Text()
	
	// Webhook URL'sini oku
	scanner.Scan()
	url := scanner.Text()
	
	// Uyarı mesajını oku
	scanner.Scan()
	message := scanner.Text()
	
	// TODO: Üç notifier türünün tümünün örneklerini oluştur
	// - prefix ile ConsoleNotifier
	// - filename ile FileNotifier
	// - URL ile WebhookNotifier
	
	// TODO: Üç notifier'ın hepsini içeren bir Notifier dilimi oluştur
	
	// TODO: BroadcastAlert'i notifiers ve message ile çağır
	
	_ = prefix
	_ = filename
	_ = url
	_ = message
	fmt.Println("TODO: 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

Kendi başına pratik yap: Online Go derleyicisi