Metot Zincirleme
Coddy'nin GO Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 81 / 107.
Metot zincirleme, metotların alıcıyı döndürerek tek bir ifadede birden çok metot çağrısının birbirine bağlanmasını sağlayan bir tekniktir. Bunu Builder deseninde zaten gördünüz, ancak birçok bağlamda yararlı olan bağımsız bir kavramdır.
Önemli nokta, her metottan struct'a 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 dil gibi okunur. Yöntem zincirleme, işlemler başka değerler döndürmeye gerek kalmadan bir nesneyi yapılandırdığında veya değiştirdiğinde en iyi şekilde çalışır. Genellikle sorgu oluşturucularda, yapılandırma API'lerinde ve test doğrulama kitaplıklarında kullanılır.
Zincirin düzgün çalışması için her metodun bir işaretçi alıcı kullanması ve *StructType döndürmesi gerektiğini unutma.
Görev
KolayÖzniteliklere ve içeriğe sahip HTML etiketleri oluşturmak için metot zincirleme kullanan akıcı bir HTML öğesi oluşturucu geliştirelim! Bu, metot zincirlemenin pratik bir uygulamasıdır: HTML öğeleri oluştururken neredeyse doğal dil gibi okunan bir API oluşturacaksınız.
Kodunuzu iki dosyaya ayıracaksınız:
element.go: Zincirlenebilir metotlarla HTML öğesi oluşturucunuzu tanımlayın.Etiket adını, özniteliklerden (string'den string'e) oluşan bir eşlemeyi ve içeriği saklayan bir
Elementyapısı oluşturun. Her biri*Elementdöndüren şu zincirlenebilir metotları geliştirin:NewElement(tag string)- verilen etiket adıyla yeni bir Element oluşturan ve başlatılmış (boş) bir öznitelik eşlemesi sağlayan yapıcı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çeriğini ayarlar
HTML dizesini döndüren bir
Render()metodu ekleyin. Öznitelikler, anahtara göre alfabetik sırada görünmelidir. Biçim şöyledir:<tag attr1="value1" attr2="value2">content</tag>Öznitelik yoksa yalnızca
<tag>content</tag>oluşturun. İçerik yoksa<tag attr="value"></tag>oluşturun.main.go: Metot zincirleme kullanarak HTML öğeleri oluşturun.Etiket adını, ardından gerçekleştirilecek işlem sayısını okuyun. Her işlem şunlardan biridir:
idve ardından ID değericlassve ardından class 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 zincirleyin, ardından oluşturulan HTML'yi yazdırın.
Aşağıdaki girdiler sağlanacaktır:
- 1. satır: Etiket adı
- 2. satır: İşlem sayısı
- Sonraki satırlar: İşlem türü ve değer(ler)i
Örneğin, şu veriler verildiğinde:
div
3
id
container
class
main-content
content
Hello WorldÇıktınız şöyle olmalıdır:
<div class="main-content" id="container">Hello World</div>Ve şu veriler verildiğinde:
a
3
attr
href
https://example.com
attr
target
_blank
content
Click hereÇıktınız şöyle olmalıdır:
<a href="https://example.com" target="_blank">Click here</a>Ve şu veriler verildiğinde:
input
2
attr
type
text
attr
placeholder
Enter nameÇıktınız şöyle olmalıdır:
<input placeholder="Enter name" type="text"></input>Ve şu veriler verildiğinde:
p
1
content
Simple paragraphÇıktınız şöyle olmalıdır:
<p>Simple paragraph</p>Metot zincirlemenin, öğeleri okunabilir bir şekilde adım adım oluşturmanıza nasıl olanak tanıdığına dikkat edin. Her metot öğeyi değiştirir ve onu döndürür; böylece bir sonraki metot çağrısı doğrudan zincirlenebilir.
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 işlemi işle
for i := 0; i < numOps; i++ {
scanner.Scan()
operation := scanner.Text()
// TODO: İşlem türüne göre 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ı class değeri olarak oku
// - "attr" için: sonraki İKİ satırı oku (ö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 zincirlemesi kullan
_ = operation // Uygularken bu satırı kaldır
}
// Render edilmiş 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ışKendi başına pratik yap: Online Go derleyicisi