Menu
Coddy logo textTech

Metot Zincirleme

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

Metot zincirleme (Method chaining), metotların alıcıyı (receiver) döndürdüğü ve tek bir ifadede birden fazla metot çağrısının birbirine bağlanmasına olanak tanıyan bir tekniktir. Bunu Builder deseninde zaten gördünüz, ancak birçok bağlamda yararlı olan bağımsız bir kavramdır.

İşin püf noktası, her metottan yapıya (struct) bir işaretçi döndürmektir:

type Query struct {
    table   string
    columns []string
    where   string
    limit   int
}

func (q *Query) Select(cols ...string) *Query {
    q.columns = cols
    return q
}

func (q *Query) From(table string) *Query {
    q.table = table
    return q
}

func (q *Query) Where(condition string) *Query {
    q.where = condition
    return q
}

func (q *Query) Limit(n int) *Query {
    q.limit = n
    return q
}

Artık bu çağrıları akıcı bir şekilde zincirleyebilirsiniz:

query := &Query{}
query.Select("name", "email").From("users").Where("active = true").Limit(10)

Bu, ayrı ifadelerle karşılaştırıldığında neredeyse doğal bir dil gibi okunur. Metot zincirleme (Method chaining), işlemlerin başka değerler döndürmeye gerek kalmadan bir nesneyi yapılandırdığı veya değiştirdiği durumlarda en iyi şekilde çalışır. Sorgu oluşturucularda, yapılandırma API'lerinde ve test doğrulama kütüphanelerinde yaygın olarak kullanılır.

Zincirin düzgün çalışması için her bir metodun bir pointer receiver kullanması ve *StructType döndürmesi gerektiğini unutmayın.

challenge icon

Görev

Kolay

Öznitelikler ve içerik içeren HTML etiketleri oluşturmak için metot zincirleme (method chaining) kullanan akıcı bir HTML öğesi oluşturucu (builder) inşa edelim! Bu, metot zincirlemenin pratik bir uygulamasıdır; HTML öğeleri oluştururken neredeyse doğal bir dil gibi okunan bir API oluşturacaksınız.

Kodunuzu iki dosya halinde düzenleyeceksiniz:

  • element.go: Zincirlenebilir metotlara sahip HTML öğesi oluşturucunuzu tanımlayın.

    Etiket adını, bir öznitelik haritasını (string'den string'e) ve iç içeriği saklayan bir Element yapısı (struct) oluşturun. Her biri *Element döndüren şu zincirlenebilir metotları oluşturun:

    • NewElement(tag string) - verilen etiket adıyla ve başlatılmış (boş) bir öznitelik haritasıyla yeni bir Element oluşturan yapıcı (constructor)
    • Attr(key, value string) - öğeye bir öznitelik ekler
    • ID(id string) - "id" özniteliğini ayarlayan kolaylık metodu
    • Class(class string) - "class" özniteliğini ayarlayan kolaylık metodu
    • Content(text string) - öğenin iç içeriğini ayarlar

    HTML dizesini döndüren bir Render() metodu ekleyin. Öznitelikler, anahtara (key) göre alfabetik sırada görünmelidir. Format şöyledir:

    <tag attr1="value1" attr2="value2">content</tag>

    Eğer öznitelik yoksa, sadece <tag>content</tag> şeklinde render edin. Eğer içerik yoksa, <tag attr="value"></tag> şeklinde render edin.

  • main.go: Metot zincirleme kullanarak HTML öğeleri oluşturun.

    Etiket adını okuyun, ardından gerçekleştirilecek işlem sayısını okuyun. Her işlem şunlardan biridir:

    • id ve ardından ID değeri
    • class ve ardından sınıf değeri
    • attr ve ardından öznitelik adı ve değeri (iki satır)
    • content ve ardından içerik metni

    Tüm işlemleri akıcı bir şekilde birbirine zincirleyin, ardından render edilmiş HTML'i yazdırın.

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

  • Satır 1: Etiket adı
  • Satır 2: İşlem sayısı
  • Sonraki satırlar: İşlem türü ve değer(ler)i

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

div
3
id
container
class
main-content
content
Hello World

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

<div class="main-content" id="container">Hello World</div>

Ve şu girdi verildiğinde:

a
3
attr
href
https://example.com
attr
target
_blank
content
Click here

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

<a href="https://example.com" target="_blank">Click here</a>

Ve şu girdi verildiğinde:

input
2
attr
type
text
attr
placeholder
Enter name

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

<input placeholder="Enter name" type="text"></input>

Ve şu girdi verildiğinde:

p
1
content
Simple paragraph

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

<p>Simple paragraph</p>

Metot zincirlemenin, öğeleri adım adım okunabilir bir şekilde oluşturmanıza nasıl olanak tanıdığına dikkat edin. Her metot öğeyi değiştirir ve onu geri döndürür, böylece bir sonraki metot çağrısının doğrudan zincirlenmesine izin verir.

Kopya kağıdı

Metot zincirleme (method chaining), metotların alıcıyı (genellikle *StructType) döndürdüğü ve birden fazla metot çağrısının tek bir ifadede birbirine bağlanmasına olanak tanıyan bir tekniktir.

Her metot bir işaretçi alıcısı (pointer receiver) kullanmalı ve *StructType döndürmelidir:

type Query struct {
    table   string
    columns []string
    where   string
    limit   int
}

func (q *Query) Select(cols ...string) *Query {
    q.columns = cols
    return q
}

func (q *Query) From(table string) *Query {
    q.table = table
    return q
}

func (q *Query) Where(condition string) *Query {
    q.where = condition
    return q
}

func (q *Query) Limit(n int) *Query {
    q.limit = n
    return q
}

Metot çağrılarını akıcı bir şekilde zincirleyin:

query := &Query{}
query.Select("name", "email").From("users").Where("active = true").Limit(10)

Metot zincirleme, işlemlerin başka değerler döndürmeye gerek kalmadan bir nesneyi yapılandırdığı veya değiştirdiği durumlarda en iyi sonucu verir. Yaygın olarak sorgu oluşturucularda (query builders), yapılandırma API'lerinde ve test doğrulama (assertion) kütüphanelerinde kullanılır.

Kendin dene

package main

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

func main() {
	scanner := bufio.NewScanner(os.Stdin)

	// Etiket adını oku
	scanner.Scan()
	tagName := scanner.Text()

	// İşlem sayısını oku
	scanner.Scan()
	numOps, _ := strconv.Atoi(scanner.Text())

	// Öğeyi oluştur
	element := NewElement(tagName)

	// Her bir işlemi işle
	for i := 0; i < numOps; i++ {
		scanner.Scan()
		operation := scanner.Text()

		// TODO: İşlem türüne bağlı olarak, uygun metodu zincirle
		// İşlemler şunlar olabilir: "id", "class", "attr" veya "content"
		// - "id" için: sonraki satırı ID değeri olarak oku
		// - "class" için: sonraki satırı sınıf değeri olarak oku
		// - "attr" için: sonraki İKİ satırı oku (önce öznitelik adı, sonra değer)
		// - "content" için: sonraki satırı içerik metni olarak oku
		// Öğeyi akıcı bir şekilde oluşturmak için metod zincirlemeyi kullanın

		_ = operation // Uygularken bu satırı kaldırın
	}

	// Oluşturulan HTML'i yazdır
	fmt.Println(element.Render())
}
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