Gömme vs Agregasyon
Coddy'nin GO Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 38 / 107.
Alanları ve yöntemleri dış yapıya yükselttiğini gömmenin sayesinde öğrendin. Ancak Go, başka bir yapıyı adlandırılmış bir alan olarak eklediğin toplamayı da destekler. Her yaklaşımı ne zaman kullanacağını anlamak, iyi bir tasarım için çok önemlidir.
Gömme ile alan adını belirtmezsiniz ve iç türün üyelerine doğrudan erişilebilir:
type Writer struct{}
func (w Writer) Write() string { return "writing" }
type Document struct {
Writer // gömme - alan adı yok
}
d := Document{}
d.Write() // doğrudan erişim
Toplulaştırma ile alana açık bir ad verirsiniz ve iç türe erişmek için bu adın kullanılmasını zorunlu kılarsınız:
type Document struct {
writer Writer // aggregation - isimli alan
}
d := Document{writer: Writer{}}
d.writer.Write() // alan adını kullanmalısın
Temel fark, ifade ettiğiniz ilişkidir. İç içe yerleştirme, dış türün iç türün kimliğini üstlendiği “bir” ilişkisini ifade eder. Toplama, dış türün yalnızca iç türü içerdiği “sahip” ilişkisini ifade eder.
İç tür tarafından uygulanan arayüzleri dış türün karşılamasını istediğinizde veya doğrudan yöntem erişimi API'yi daha temiz hâle getirdiğinde gömme kullanın. İç türün açığa çıkarılmaması gereken bir uygulama ayrıntısı olduğu durumlarda veya iç türe nasıl erişileceği üzerinde açıkça kontrol sahibi olmak istediğinizde toplama kullanın.
Görev
KolayGömmenin ve toplamanın ne zaman kullanılacağını gösteren bir rapor oluşturma sistemi geliştirelim. Bazı bileşenlere doğrudan erişilebilen (gömme), diğerlerinin ise dahili uygulama ayrıntıları olarak kalması gereken bir sistem oluşturacaksınız (toplama).
Kodunuzu üç dosya arasında düzenleyeceksiniz:
formatter.go: BirFormatteralanına (string) ve metni stil ile sarılmış şekilde, örneğinStyle, döndüren birFormat(text string) stringmetoduna sahip bir[Style] text [/Style]struct'ı oluşturun. Bu, doğrudan dışarı açılmaması gereken dahili bir yardımcı olacaktır.report.go: Rapor oluşturmayı farklı şekillerde ele alan iki struct oluşturun:MetadataveAuthoralanlarına sahip birDatestruct'ı. Bu, doğrudan erişilebilir olması gereken herkese açık bilgileri temsil eder- Doğrudan yazar ve tarihe erişim için
Report'yı gömen, ancakTitleiçin (isimlendirilmişMetadataalanına sahip dahili bir uygulama ayrıntısı olarak) toplama kullanan,Formatteralanına sahip birformatterstruct'ı
Generate() string'a, başlığı biçimlendirmek için dahili biçimlendiriciyi kullanan ve meta verileri içeren birReportmetodu ekleyin.main.go: Rapor ayrıntılarını girdiden okuyun, hem gömülü meta verileri hem de toplanmış bir biçimlendiricisi olan birReportoluşturun. Yazara rapor üzerinden doğrudan erişerek (gömme yoluyla) ve ardından biçimlendirilmiş raporu oluşturarak (dahili olarak gizli biçimlendiriciyi kullanır) farkı gösterin.
Aşağıdaki girdiler sağlanacaktır:
- 1. satır: Rapor başlığı
- 2. satır: Yazar adı
- 3. satır: Tarih
- 4. satır: Biçimlendirici stili
Format metodunuz şunu döndürmelidir:
[Style] text [/Style]Generate metodunuz şunu döndürmelidir:
[formatted title]
Author: [Author], Date: [Date]main dosyanızda üç satır yazdırın:
- Report üzerinde doğrudan erişilen yazar (gömmenin alanı öne çıkardığını gösterir)
- Gömülü tür adı üzerinden erişilen tarih (
report.Metadata.Date) Generate()çağrısının sonucu
Örneğin, Quarterly Results, Jane Doe, 2024-01-15 ve BOLD verildiğinde çıktınız şöyle olmalıdır:
Jane Doe
2024-01-15
[BOLD] Quarterly Results [/BOLD]
Author: Jane Doe, Date: 2024-01-15Author ve Date'e gömme yoluyla Report üzerinde doğrudan erişilebildiğine, biçimlendiricinin ise gizli kaldığına dikkat edin. İsimlendirilmiş bir alanla toplandığı için doğrudan report.Format() çağrısı yapamazsınız. Bu, uygulamada “bir şeydir” ve “bir şeye sahiptir” ilişkilerini gösterir.
Kendin dene
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
title := scanner.Text()
scanner.Scan()
author := scanner.Text()
scanner.Scan()
date := scanner.Text()
scanner.Scan()
style := scanner.Text()
// TODO: author ve date ile bir Metadata struct'ı oluştur
// TODO: verilen style ile bir Formatter oluştur
// TODO: Metadata'yı gömen ve Formatter'ı birleştiren bir Report oluştur
// TODO: Report üzerinde doğrudan erişilen author'ı yazdır (gömme alanı yükseltir)
// TODO: gömülü tip adı üzerinden erişilen date'i yazdır (report.Metadata.Date)
// TODO: Generate() çağrısının sonucunu yazdır
// Kullanılmayan değişken uyarılarını bastır (değişkenleri kullandığında bunları kaldır)
_ = title
_ = author
_ = date
_ = style
}
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 PoolKendi başına pratik yap: Online Go derleyicisi