Menu
Coddy logo textTech

Go'da Bilgi Gizleme

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

Bilgi gizleme, yalnızca alanları dışa aktarılmamış hâle getirmenin ötesine geçer. Mesele, türlerinizi dış kodun yalnızca bilmesi gerekenleri bilecek şekilde tasarlamaktır. Daha fazlasını değil.

Amaç, iç yapıyı tamamen gizli tutarken metotlar aracılığıyla davranışı ortaya koymaktır. Şu yaklaşımı göz önünde bulundurun:

type Counter struct {
    value    int
    maxLimit int
}

func NewCounter(limit int) *Counter {
    return &Counter{maxLimit: limit}
}

func (c *Counter) Increment() bool {
    if c.value >= c.maxLimit {
        return false
    }
    c.value++
    return true
}

func (c *Counter) Value() int {
    return c.value
}

Harici kod, Counter öğesinin dahili olarak bir int kullandığını bilmez. Bu, bir float64, bir dilim veya tamamen başka bir şey olabilir. Yöntemler aynı şekilde davrandığı sürece, Counter kullanan hiçbir kod etkilenmeden uygulama değiştirilebilir.

Bu ilke yardımcı işlevler için de geçerlidir. İç mantığı dışa aktarmayın:

// Exported - public API'nin parçası
func (c *Counter) Reset() {
    c.value = 0
}

// unexported - dahili yardımcı
func (c *Counter) isAtLimit() bool {
    return c.value >= c.maxLimit
}

isAtLimit() öğesini gizleyerek, daha sonra onu değiştirmekte veya kaldırmakta özgürsünüz. Bilgi gizleme, paketinizin harici kullanıcılara ne vaat ettiği ile dahili olarak nasıl çalıştığı arasında net bir sınır oluşturur.

challenge icon

Görev

Kolay

Bilgi gizlemeyi gösteren güvenli bir cüzdan sistemi oluşturalım. Dahili bakiye takibinin ve işlem geçmişinin harici koddan tamamen gizlendiği bir dijital cüzdan oluşturacaksın: yalnızca davranış metotlar aracılığıyla açığa çıkarılacak.

Kodunu iki dosyaya ayıracaksın:

  • wallet.go: Tüm dahili durumunu gizleyen bir Wallet yapısı oluştur. Cüzdan, mevcut bakiyeyi ve harcama limitini dahili olarak takip etmeli; ancak harici kod bunların nasıl saklandığını veya temsil edildiğini asla bilmemeli. Davranışı şu metotlar aracılığıyla açığa çıkar:
    • NewWallet(limit float64) *Wallet - verilen harcama limitiyle ve sıfır bakiyeyle bir cüzdan oluşturan oluşturucu
    • Deposit(amount float64) bool - cüzdana para ekler, başarılıysa true döndürür (miktar pozitif olmalıdır)
    • Spend(amount float64) bool - yeterli bakiye varsa VE miktar harcama limitini aşmıyorsa parayı çıkarır, başarılıysa true döndürür
    • Balance() float64 - mevcut bakiyeyi döndürür
    • Status() string - şu biçimde bir durum mesajı döndürür: Balance: $[balance] (Limit: $[limit])
    Yardımcı mantığı (bir işlemin geçerli olup olmadığını kontrol etmek gibi) dışa aktarılmamış işlevler veya metotlar olarak tut. Bunlar daha sonra değişebilecek dahili uygulama ayrıntılarıdır.
  • main.go: Cüzdan yapılandırmasını ve işlemleri girdiden oku, bir cüzdan oluştur, işlemleri gerçekleştir ve her eylemden sonra sonuçları görüntüle.

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

  • 1. satır: Harcama limiti
  • 2. satır: Para yatırma miktarı
  • 3. satır: İlk harcama miktarı
  • 4. satır: İkinci harcama miktarı

Cüzdanı oluşturduktan sonra başlangıç durumunu yazdır. Ardından her işlemi gerçekleştir ve başarılıysa güncellenmiş durumu, işlem reddedildiyse Transaction failed yazdır. Tüm dolar miktarlarını iki ondalık basamakla biçimlendir.

Örneğin 50, 100, 30 ve 80 verildiğinde çıktın şu şekilde olmalıdır:

Balance: $0.00 (Limit: $50.00)
Balance: $100.00 (Limit: $50.00)
Balance: $70.00 (Limit: $50.00)
Transaction failed

Son işlem başarısız olur çünkü $80, yeterli bakiye olmasına rağmen $50 harcama limitini aşar. Cüzdan, bu kararları nasıl verdiğini açığa çıkarmadan kurallarını dahili olarak uygular. Harici kod yalnızca metotları çağırır ve sonuçları alır; dahili uygulama ayrıntılarını asla bilmez.

Kendin dene

package main

import (
	"fmt"
)

func main() {
	// Girdileri oku
	var limit float64
	var depositAmount float64
	var spend1 float64
	var spend2 float64

	fmt.Scanln(&limit)
	fmt.Scanln(&depositAmount)
	fmt.Scanln(&spend1)
	fmt.Scanln(&spend2)

	// TODO: Verilen harcama limiti ile yeni bir cüzdan oluştur

	// TODO: İlk durumu yazdır

	// TODO: Perform deposit and print result (status or "Transaction failed")

	// TODO: İlk harcamayı gerçekleştir ve sonucu yazdır

	// TODO: İkinci harcamayı gerçekleştir ve sonucu yazdır
}
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