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, alanları sadece dışa aktarılmamış (unexported) hale getirmenin ötesine geçer. Bu, türlerinizi harici kodun sadece bilmesi gerekeni bileceği, daha fazlasını bilmeyeceği şekilde tasarlamakla ilgilidir.

Amaç, dahili yapıyı tamamen gizli tutarken metotlar aracılığıyla davranışı ortaya çıkarmaktır. Şu yaklaşımı düşünün:

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 yapısının dahili olarak bir int kullandığını bilmez. Bu bir float64, bir slice veya tamamen başka bir şey olabilir. Uygulama, metotlar aynı şekilde davrandığı sürece Counter kullanan herhangi bir kodu etkilemeden değişebilir.

Bu ilke yardımcı fonksiyonlar için de geçerlidir. Dahili mantığı dışa aktarılmamış (unexported) olarak tutun:

// Dışa aktarılan - genel API'nin bir parçası
func (c *Counter) Reset() {
    c.value = 0
}

// dışa aktarılmayan - dahili yardımcı
func (c *Counter) isAtLimit() bool {
    return c.value >= c.maxLimit
}

isAtLimit() fonksiyonunu gizleyerek, onu daha sonra değiştirme veya kaldırma konusunda özgür olursunuz. Bilgi gizleme, paketinizin dış kullanıcılara vaat ettikleri ile dahili olarak nasıl çalıştığı arasında net bir sınır oluşturur.

challenge icon

Görev

Kolay

Bilgi gizlemeyi (information hiding) gösteren güvenli bir cüzdan sistemi inşa edelim. Dahili bakiye takibinin ve işlem geçmişinin harici koddan tamamen gizlendiği, yalnızca davranışların metotlar aracılığıyla sunulduğu bir dijital cüzdan oluşturacaksınız.

Kodunuzu iki dosya halinde düzenleyeceksiniz:

  • wallet.go: Tüm dahili durumunu gizleyen bir Wallet yapısı (struct) oluşturun. Cüzdan, mevcut bakiyeyi ve harcama limitini dahili olarak takip etmelidir, ancak harici kod bunların nasıl saklandığını veya temsil edildiğini asla bilmemelidir. Davranışları şu metotlar aracılığıyla sunun:
    • NewWallet(limit float64) *Wallet - verilen harcama limiti ve sıfır bakiye ile bir cüzdan oluşturan yapıcı (constructor) fonksiyon
    • Deposit(amount float64) bool - cüzdana para ekler, başarılıysa (miktar pozitif olmalıdır) true döner
    • Spend(amount float64) bool - yeterli bakiye varsa VE miktar harcama limitini aşmıyorsa parayı çeker, başarılıysa true döner
    • Balance() float64 - mevcut bakiyeyi döner
    • Status() string - şu formatta bir durum mesajı döner: "Balance: $[balance] (Limit: $[limit])"
    İşlemin geçerli olup olmadığını kontrol etmek gibi yardımcı mantıkları dışa aktarılmayan (unexported) fonksiyonlar veya metotlar olarak tutun; bunlar daha sonra değişebilecek dahili uygulama detaylarıdır.
  • main.go: Girdiden cüzdan yapılandırmasını ve işlemleri okuyun, bir cüzdan oluşturun, işlemleri gerçekleştirin ve her eylemden sonra sonuçları görüntüleyin.

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

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

Cüzdanı oluşturduktan sonra başlangıç durumunu yazdırın. Ardından her işlemi gerçekleştirin ve ya güncellenmiş durumu (başarılıysa) ya da "Transaction failed" (işlem reddedildiyse) yazdırın. Tüm dolar miktarlarını iki ondalık basamakla formatlayın.

Örneğin, 50, 100, 30 ve 80 verildiğinde çıktınız şöyle 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ü yeterli bakiye olmasına rağmen $80, $50 olan harcama limitini aşmaktadır. Cüzdan, bu kararları nasıl verdiğini ifşa etmeden kurallarını dahili olarak uygular. Harici kod sadece metotları çağırır ve sonuçları alır, dahili uygulama detayları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şturun

	// TODO: Başlangıç durumunu yazdırın

	// TODO: Para yatırma işlemini gerçekleştirin ve sonucu yazdırın (durum veya "Transaction failed")

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

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