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.
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
Elementyapısı (struct) oluşturun. Her biri*Elementdö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 eklerID(id string)- "id" özniteliğini ayarlayan kolaylık metoduClass(class string)- "class" özniteliğini ayarlayan kolaylık metoduContent(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:
idve ardından ID değericlassve ardından sınıf değeriattrve ardından öznitelik adı ve değeri (iki satır)contentve 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())
}
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
1Go OOP Temelleri
Harici DosyalarGo Çalışma Alanı ve ModüllerPaketler ve İçe AktarmalarDışa Aktarılan ve Aktarılmayan İsimlerGo'da OOP'ye GirişSınıf Olarak Struct'larStruct'larda Metot TanımlamaPointer ve Değer AlıcılarStruct BaşlatmaYapıcı FonksiyonlarÖzet - Basit Hesap Makinesi4Arayüzler
Arayüzlere GirişÖrtük UygulamaSözleşme Olarak ArayüzBoş Arayüz (any)Tür OnaylamaTür SeçimiArayüz BileşimiStringer ve Error ArayüzleriÖzet - Şekil Hesaplayıcı7Kapsülleme
Dışa Aktarılan ve Aktarılmayan AlanlarPaket Seviyesinde KapsüllemeGetter ve Setter MetotlarıGo'da Bilgi GizlemeÖzet - Öğrenci Kayıtları10Generics (Go 1.18+)
Generics'e GirişTür ParametreleriTür KısıtlamalarıGeneric Struct'larGeneric Metotlar İçin Geçici ÇözümÖzet - Generic Koleksiyon13Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişSingleton KalıbıFactory KalıbıAbstract Factory KalıbıObserver KalıbıStrategy Kalıbı2Türler ve Struct'lar: Derinlemesine İnceleme
Temel ve Bileşik TürlerÖzel Tür TanımlamalarıStruct EtiketleriAnonim Struct'larİç İçe Geçmiş Struct'larSıfır Değerler ve VarsayılanlarÖzet - Rehber5Kalıtım Yerine Kompozisyon
Go'da Neden Kalıtım YokStruct Gömme TemelleriMetot YükseltmeBirden Fazla Struct GömmeGömme vs AgregasyonGömülü Metotları GölgelemeÖzet - Çalışan Hiyerarşisi8Hata Yönetimi ve OOP
error ArayüzüÖzel Hata TürleriHata Sarmalama (fmt.Errorf)Sentinel Hatalarerrors.Is() ve errors.As()Panic, Defer ve RecoverÖzet - Dosya Ayrıştırıcı3İşaretçiler ve Bellek
Go'da İşaretçi TemelleriStruct İşaretçileriDeğer ile Geçme ve Referans ile Geçmenew() FonksiyonuGo'da Garbage CollectionÖzet - Linked List Oluşturucu6Go'da Polimorfizm
Interface'ler ile PolimorfizmGo'da Duck TypingInterface Karşılama KurallarıPolimorfik KoleksiyonlarDependency InjectionÖzet - Payment Processor9Eşzamanlılık ve OOP
Goroutine TemelleriKanallar ve İletişimTamponlu ve Tamponsuz KanallarSelect İfadesisync.Mutex ve sync.RWMutexsync.WaitGroupThread-Safe Struct TasarımıÖzet - Worker Pool12İleri Düzey OOP Kavramları
Functional Options DeseniGo'da Builder DeseniMetot ZincirlemeTür Takma Adları vs. TanımlamalarReflection TemelleriKod Üretimine Genel Bakış