Menu
Coddy logo textTech

Paket Seviyesinde Kapsülleme

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

Önceki derste alan düzeyindeki görünürlük ele alınmış olsa da Go'nun kapsülleme mekanizması aslında paket düzeyinde çalışır. Dosyanın hangisinde bulunduğuna bakılmaksızın aynı paket içindeki her şey, dışa aktarılmamış alanlara ve işlevlere erişebilir.

Birden fazla dosya içeren bir paketi göz önünde bulundurun:

// account/account.go
package account

type Account struct {
    balance int  // dışa aktarılmamış
}

func (a *Account) Deposit(amount int) {
    a.balance += amount
}
// account/helper.go
package account

func ResetAccount(a *Account) {
    a.balance = 0  // çalışır - aynı paket
}

Her iki dosya da account paketine aittir; bu nedenle helper.go, dışa aktarılmamış balance alanına directly erişebilir. Bu kasıtlıdır. Paket içi erişimi korurken paket mantığını dosyalar arasında bölmenize olanak tanır.

Ancak paketin dışındaki kod, dışa aktarılmamış üyelere erişemez:

// main.go
package main

import "account"

func main() {
    acc := &account.Account{}
    acc.Deposit(100)        // çalışır - dışa aktarılmış metot
    // acc.balance = 50     // hata - dışa aktarılmamış alan
    // account.ResetAccount // ResetAccount dışa aktarılmış olsaydı çalışır
}

Bu paket düzeyi sınırı, Go’nun temel kapsülleme mekanizmasıdır. Paketleri, iç kodun özgürce iş birliği yaptığı, dış kodun ise yalnızca dışa aktarılan API aracılığıyla etkileşim kurduğu uyumlu birimler olarak tasarlarsınız. Her paketi, net bir genel arayüze sahip, kendi kendine yeten bir modül olarak düşünün.

challenge icon

Görev

Kolay

Aynı paket içindeki birden fazla dosyanın, dış koddaki verileri gizli tutarken dışa aktarılmamış alanlara doğrudan erişerek nasıl birlikte çalışabileceğini gösteren bir envanter yönetim sistemi oluşturalım.

main paketinde birlikte çalışan üç dosya oluşturacaksın:

  • product.go: Dışa aktarılmış bir Product alanına ve dışa aktarılmamış bir Name alanına (int) sahip bir quantity yapısı tanımla. Info() string biçimini döndüren dışa aktarılmış bir [Name]: [quantity] in stock metodu ekle.
  • inventory.go: Dışa aktarılmamış quantity alanına doğrudan erişerek ürünlerle çalışan yardımcı fonksiyonlar oluştur (aynı pakette oldukları için bu mümkündür). Şunları uygula:
    • Restock(p *Product, amount int) - miktarı ürünün quantity değerine ekler
    • Sell(p *Product, amount int) bool - yeterli stok varsa miktarı quantity değerinden çıkarır; işlem başarılıysa true, yeterli stok yoksa false döndürür
    • NewProduct(name string, initialQty int) *Product - verilen ad ve başlangıç miktarıyla bir ürün oluşturan kurucu
  • main.go: Ürün bilgilerini girdiden oku, kurucuyu kullanarak bir ürün oluştur, envanter işlemlerini gerçekleştir ve sonuçları görüntüle. Güncellenmiş durumu göstermek için her işlemden sonra ürün bilgilerini yazdır.

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

  • 1. satır: Ürün adı
  • 2. satır: Başlangıç miktarı (tam sayı)
  • 3. satır: Stok yenileme miktarı (tam sayı)
  • 4. satır: Satış miktarı (tam sayı)

Ürünü oluşturduktan sonra başlangıç bilgilerini yazdır. Ardından stok yenileme işlemini gerçekleştir ve bilgileri tekrar yazdır. Son olarak satışı gerçekleştirmeyi dene ve başarılıysa güncellenmiş bilgileri, miktar yeterli değilse Sale failed: insufficient stock ifadesini yazdır.

Örneğin, Laptop, 10, 5 ve 8 verildiğinde çıktın şu şekilde olmalıdır:

Laptop: 10 in stock
Laptop: 15 in stock
Laptop: 7 in stock

Ve Phone, 3, 2 ve 10 verildiğinde çıktın şu şekilde olmalıdır:

Phone: 3 in stock
Phone: 5 in stock
Sale failed: insufficient stock

Buradaki temel çıkarım, inventory.go dosyasının dışa aktarılmamış quantity alanını doğrudan okuyup değiştirebilmesidir; çünkü product.go ile aynı pakettedir. Bu, paket düzeyinde kapsüllemenin işleyiş hâlidir: dahili iş birliği serbestçe gerçekleşirken veriler dış paketlerden korunmaya devam eder.

Kendin dene

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	// Ürün adını oku
	name, _ := reader.ReadString('\n')
	name = strings.TrimSpace(name)

	// Başlangıç miktarını oku
	initialQtyStr, _ := reader.ReadString('\n')
	initialQty, _ := strconv.Atoi(strings.TrimSpace(initialQtyStr))

	// Yeniden stok miktarını oku
	restockStr, _ := reader.ReadString('\n')
	restockAmount, _ := strconv.Atoi(strings.TrimSpace(restockStr))

	// Satış miktarını oku
	sellStr, _ := reader.ReadString('\n')
	sellAmount, _ := strconv.Atoi(strings.TrimSpace(sellStr))

	// TODO: NewProduct yapıcısını kullanarak yeni bir ürün oluştur

	// TODO: Başlangıç ürün bilgisini yazdır

	// TODO: Ürünü yeniden stokla ve bilgiyi yazdır

	// TODO: Satış yapmayı dene ve sonucu yazdır
	// Satış başarılı olursa, güncellenmiş bilgiyi yazdır
	// If sale fails, print "Sale failed: insufficient stock"

	fmt.Println() // Gerçek çıktı ile değiştir
}
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