Setter Metotlarında Doğrulama
Coddy'nin C Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 20 / 61.
Önceki derste, sadece değer atayan temel setter'lar oluşturduk. Ancak bu, kapsüllemenin (encapsulation) temel bir avantajını kaçırır: doğrulama mantığı ekleyerek verilerinizi koruma yeteneği.
Asla negatif olmaması gereken bir Counter düşünün. Kapsülleme olmadan, herkes c->value = -50 yazabilir ve durumu bozabilir. Bir setter ile hangi değerlere izin verileceğini kontrol edersiniz:
// counter.c
void counter_set_value(Counter *c, int new_value) {
if (new_value < 0) {
return; // Geçersiz girişi sessizce reddet
}
c->value = new_value;
}Artık negatif değerler doğrudan yok sayılıyor.
Başarıyı veya başarısızlığı belirtmek için bir durum kodu döndürmeyi de seçebilirsiniz:
int counter_set_value(Counter *c, int new_value) {
if (new_value < 0) {
return 0; // Başarısızlık
}
c->value = new_value;
return 1; // Başarı
}Bu desen, çağıranın işlemin başarılı olup olmadığını bilmesini sağlar. Temel içgörü, setter'ların sadece atama ile ilgili olmamasıdır; onlar, nesnenizin durumunun ne olabileceğine dair kuralları uygulayan kapı bekçileridir. Kapsüllemenin (encapsulation) gerçek gücü budur: dış kod ne yapmaya çalışırsa çalışsın, nesneniz kendi bütünlüğünü korur.
Görev
KolaySetter içinde doğrulama kullanarak verilerini koruyan bir Temperature modülü oluşturalım. Yalnızca geçerli bir aralıktaki değerleri kabul eden bir sıcaklık takipçisi oluşturacaksınız; bu, setter'ların nesnenizin durumu için nasıl bekçi görevi gördüğünü gösterecektir.
Üç dosya oluşturacaksınız:
temperature.h: Opak işaretçi (opaque pointer) desenini kullanan genel arayüzünüz. Sadece bir ön bildirim (forward declaration) ile birTemperaturetürü bildirin. Şu fonksiyonları bildirin:create_temperature— başlangıç derecesi için bir tam sayı alır ve bir Temperature işaretçisi döndürürfree_temperature— ayrılan belleği serbest bırakırtemp_get_degrees— mevcut sıcaklık değerini döndüren gettertemp_set_degrees— birint(başarı için 1, başarısızlık için 0) döndüren setter
TEMPERATURE_Hsembolü ile include guard'ları kullanın.temperature.c: Gizli birint degreesüyesine sahip gerçekstruct Temperatureyapısını tanımlayın. Tüm fonksiyonları uygulayın. Anahtar nokta setter'ınızdır; yalnızca -50 ile 150 (dahil) arasındaki değerleri kabul etmelidir. Değer bu aralığın dışındaysa, 0 döndürün ve sıcaklığı değiştirmeden bırakın. Geçerliyse, değeri güncelleyin ve 1 döndürün.main.c: Hem geçerli hem de geçersiz sıcaklıkları ayarlamaya çalışarak doğrulamayı gösterin; geçersiz değerlerin reddedildiğini, geçerli olanların ise kabul edildiğini gösterin.
Üç girdi alacaksınız: başlangıç sıcaklığı, ayarlanacak geçerli bir sıcaklık (aralık içinde) ve denenecek geçersiz bir sıcaklık (aralık dışında).
Ana dosyanızda, başlangıç değeriyle bir Temperature oluşturun ve bunu yazdırın. Ardından geçersiz sıcaklığı ayarlamaya çalışın; reddedilmesi gerektiği için sonucu yazdırın ve değerin değişmeden kaldığını gösterin. Son olarak, geçerli sıcaklığı ayarlayın, başarı sonucunu yazdırın ve güncellenmiş değeri gösterin. Belleği serbest bırakın ve temizliği onaylayın.
Çıktıyı şu formatta yazdırın:
Initial: {degrees}
Set {invalid}: {0 or 1}
After invalid: {degrees}
Set {valid}: {0 or 1}
After valid: {degrees}
FreedÖrneğin, 25, 100 ve 200 girdileriyle çıktı şöyle olacaktır:
Initial: 25
Set 200: 0
After invalid: 25
Set 100: 1
After valid: 100
FreedBu, kapsüllemenin (encapsulation) gerçek gücünü gösterir; setter'ınız, dış kodun hangi değerleri atamaya çalıştığına bakılmaksızın, nesnenin bütünlüğünü koruyarak neyin geçerli bir sıcaklık teşkil ettiğine dair kuralları uygular.
Kopya kağıdı
Ayarlayıcılar (Setters), veri bütünlüğünü korumak için doğrulama mantığı içerebilir. Sadece değer atamak yerine, geçerli nesne durumları hakkındaki kuralları uygulayan bekçiler (gatekeepers) gibi hareket ederler.
Temel doğrulama örneği - geçersiz girişi sessizce reddetme:
void counter_set_value(Counter *c, int new_value) {
if (new_value < 0) {
return; // Geçersiz girişi reddet
}
c->value = new_value;
}Başarıyı veya başarısızlığı belirtmek için bir durum kodu döndürme:
int counter_set_value(Counter *c, int new_value) {
if (new_value < 0) {
return 0; // Başarısızlık
}
c->value = new_value;
return 1; // Başarı
}Bu desen, çağıranların işlemin başarılı olup olmadığını kontrol etmesine olanak tanıyarak, nesnelerin dış kod girişimlerinden bağımsız olarak kendi bütünlüklerini korumalarını sağlar.
Kendin dene
#include <stdio.h>
#include "temperature.h"
int main() {
// Girdileri oku
int initial, valid_temp, invalid_temp;
scanf("%d", &initial);
scanf("%d", &valid_temp);
scanf("%d", &invalid_temp);
// TODO: Başlangıç değeri ile bir Temperature oluştur
// TODO: Başlangıç sıcaklığını yazdır
// Format: "Initial: {degrees}"
// TODO: Geçersiz sıcaklığı ayarlamayı dene
// Sonucu yazdır ve değerin değişmediğini göster
// Format: "Set {invalid}: {0 or 1}"
// Format: "After invalid: {degrees}"
// TODO: Geçerli sıcaklığı ayarla
// Başarı sonucunu yazdır ve güncellenmiş değeri göster
// Format: "Set {valid}: {0 or 1}"
// Format: "After valid: {degrees}"
// TODO: Belleği serbest bırak ve "Freed" yazdır
return 0;
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Object Oriented Programming bölümündeki tüm dersler
1Modüler Programlama Temelleri
Başlık DosyalarıInclude Guard'larKaynak DosyalarıStatik FonksiyonlarÖzet: Modüler Hesap Makinesi4Kapsülleme
Opaque Pointer KavramıOpaque Struct TanımlamaGetter ve Setter MetotlarıSetter Metotlarında DoğrulamaÖzet: Gizli Kutu2Nesneler ve Metotlar
Nesne Olarak Struct'lar'Self' İşaretçisiConst Doğruluğuİşaretçi vs DeğerYardımcı MetotlarÖzet: Point Manager5Proje: Basit Banka Hesabı
Proje KurulumuHesabın Oluşturulması3Nesne Yaşam Döngüsü
Constructor DeseniDestructor DeseniStack İlklendirmeDerin KopyalamaÖzet: String Wrapper6Kompozisyon Yoluyla Kalıtım
Struct Gömmeİlk Üye KuralıÜst Üyelere ErişimUpcastingÖzet: Şekil Hiyerarşisi