Menu
Coddy logo textTech

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.

challenge icon

Görev

Kolay

Gö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: Bir Formatter alanına (string) ve metni stil ile sarılmış şekilde, örneğin Style, döndüren bir Format(text string) string metoduna 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:
    • Metadata ve Author alanlarına sahip bir Date struct'ı. 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, ancak Title için (isimlendirilmiş Metadata alanına sahip dahili bir uygulama ayrıntısı olarak) toplama kullanan, Formatter alanına sahip bir formatter struct'ı
    Generate() string'a, başlığı biçimlendirmek için dahili biçimlendiriciyi kullanan ve meta verileri içeren bir Report metodu ekleyin.
  • main.go: Rapor ayrıntılarını girdiden okuyun, hem gömülü meta verileri hem de toplanmış bir biçimlendiricisi olan bir Report oluş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:

  1. Report üzerinde doğrudan erişilen yazar (gömmenin alanı öne çıkardığını gösterir)
  2. Gömülü tür adı üzerinden erişilen tarih (report.Metadata.Date)
  3. 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-15

Author 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
}
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