Menu
Coddy logo textTech

Go'da Builder Deseni

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

Builder Pattern, karmaşık bir nesnenin oluşturulmasını temsilinden ayırır. Functional Options deseninin aksine Builder, nesneyi adım adım yapılandıran yöntemlere sahip özel bir builder yapısı kullanır.

Bir HTTP isteği için builder'ı şu şekilde uygulayabilirsin:

type Request struct {
    method  string
    url     string
    headers map[string]string
    body    string
}

type RequestBuilder struct {
    request *Request
}

func NewRequestBuilder() *RequestBuilder {
    return &RequestBuilder{
        request: &Request{
            headers: make(map[string]string),
        },
    }
}

func (b *RequestBuilder) Method(m string) *RequestBuilder {
    b.request.method = m
    return b
}

func (b *RequestBuilder) URL(u string) *RequestBuilder {
    b.request.url = u
    return b
}

func (b *RequestBuilder) Header(key, value string) *RequestBuilder {
    b.request.headers[key] = value
    return b
}

func (b *RequestBuilder) Build() *Request {
    return b.request
}

Her yöntem, oluşturucu işaretçisini döndürerek yöntem zincirlemeyi mümkün kılar. Build() yöntemi işlemi tamamlar ve oluşturulan nesneyi döndürür:

req := NewRequestBuilder().
    Method("POST").
    URL("https://api.example.com").
    Header("Content-Type", "application/json").
    Build()

Builder deseni, nesneler birden fazla yapılandırma adımı gerektirdiğinde veya belirli bir oluşturma sırasını zorunlu kılmak istediğinizde öne çıkar. Özellikle değişmez nesneler oluşturmak ya da oluşturma sürecinin kendisinin doğrulanması gerektiğinde kullanışlıdır.

challenge icon

Görev

Kolay

Builder Pattern'ı kullanarak bir e-posta mesajı oluşturucu geliştirelim! E-posta mesajlarının alıcılar, CC, konu, gövde ve ekler gibi birçok isteğe bağlı bileşeni vardır; bu da onları yöntem zincirleme ile adım adım oluşturmak için mükemmel bir aday hâline getirir.

Kodunuzu iki dosyaya ayıracaksınız:

  • email.go: E-posta yapınızı ve oluşturucusunu tanımlayın.

    Şu alanlara sahip bir Email yapısı oluşturun:

    • from (string)
    • to (string dilimi)
    • cc (string dilimi)
    • subject (string)
    • body (string)

    Oluşturulmakta olan bir Email işaretçisini tutan bir EmailBuilder yapısı oluşturun. Başlatılmış bir Email ( NewEmailBuilder() ve to için boş dilimler) içeren yeni bir oluşturucu döndüren cc işlevini uygulayın.

    Aşağıdaki oluşturucu yöntemlerini ekleyin; her biri zincirleme için *EmailBuilder döndürmelidir:

    • From(address string) - göndereni ayarlar
    • To(address string) - to dilimine bir alıcı ekler
    • CC(address string) - cc dilimine bir alıcı ekler
    • Subject(subject string) - konu satırını ayarlar
    • Body(body string) - e-posta gövdesini ayarlar

    Oluşturulan Build() değerini döndüren bir *Email yöntemi ekleyin.

    Son olarak, Email üzerine aşağıdaki biçimde bir string döndüren bir Summary() yöntemi ekleyin:

    From: [from]
    To: [comma-separated to addresses]
    CC: [comma-separated cc addresses or "none"]
    Subject: [subject]
    Body: [body]
  • main.go: Oluşturucuyu kullanarak e-posta mesajları oluşturun ve görüntüleyin.

    Gönderen adresini, ardından alıcı sayısını ve her bir alıcı adresini okuyun. Sonra CC alıcılarının sayısını ve her bir CC adresini okuyun. Son olarak konuyu ve gövdeyi okuyun.

    E-postayı oluşturmak için yöntem zincirleme ile EmailBuilder'ı kullanın, ardından özetini yazdırın.

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

  • 1. satır: Gönderen adresi
  • 2. satır: Alıcı sayısı
  • Sonraki satırlar: Her bir alıcı adresi
  • Sonraki satır: CC alıcılarının sayısı
  • Sonraki satırlar: Her bir CC adresi
  • Sonraki satır: Konu
  • Son satır: Gövde

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

alice@company.com
2
bob@company.com
carol@company.com
1
manager@company.com
Weekly Report
Please find the weekly report attached.

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

From: alice@company.com
To: bob@company.com, carol@company.com
CC: manager@company.com
Subject: Weekly Report
Body: Please find the weekly report attached.

Ve şu girdi verildiğinde:

support@service.com
1
customer@email.com
0
Your Ticket Update
Your support ticket has been resolved.

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

From: support@service.com
To: customer@email.com
CC: none
Subject: Your Ticket Update
Body: Your support ticket has been resolved.

Oluşturucunun, tekrarlanan To() çağrıları aracılığıyla birden fazla alıcıyı birer birer eklemenize nasıl olanak tanıdığına ve isteğe bağlı birçok alan olsa bile bu kalıbın oluşturma sürecini nasıl temiz ve okunabilir tuttuğuna dikkat edin.

Kendin dene

package main

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

func main() {
	reader := bufio.NewReader(os.Stdin)

	// Gönderen adresini oku
	from, _ := reader.ReadString('\n')
	from = strings.TrimSpace(from)

	// Alıcı sayısını oku
	toCountStr, _ := reader.ReadString('\n')
	toCount, _ := strconv.Atoi(strings.TrimSpace(toCountStr))

	// Her alıcı adresini oku
	toAddresses := make([]string, toCount)
	for i := 0; i < toCount; i++ {
		addr, _ := reader.ReadString('\n')
		toAddresses[i] = strings.TrimSpace(addr)
	}

	// CC alıcı sayısını oku
	ccCountStr, _ := reader.ReadString('\n')
	ccCount, _ := strconv.Atoi(strings.TrimSpace(ccCountStr))

	// Her CC adresini oku
	ccAddresses := make([]string, ccCount)
	for i := 0; i < ccCount; i++ {
		addr, _ := reader.ReadString('\n')
		ccAddresses[i] = strings.TrimSpace(addr)
	}

	// Konuyu oku
	subject, _ := reader.ReadString('\n')
	subject = strings.TrimSpace(subject)

	// Gövdeyi oku
	body, _ := reader.ReadString('\n')
	body = strings.TrimSpace(body)

	// TODO: E-postayı oluşturmak için EmailBuilder'ı method chaining ile kullan
	// NewEmailBuilder() ile başla, ardından From(), To(), CC(), Subject(), Body() zincirle
	// Son olarak Email'i almak için Build() çağır

	// TODO: Summary() metodunu kullanarak e-posta özetini yazdır
}
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