Arayüzleri Uygulama
Coddy'nin C Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 41 / 61.
Artık bir arayüzün (interface) ne olduğunu —yalnızca fonksiyon göstericileri (function pointers) içeren bir struct— anladığınıza göre, bu sözleşmeyi yerine getiren somut uygulamalar (concrete implementations) oluşturma zamanı geldi.
Önceki dersteki ILogger arayüzünü hatırlayalım:
typedef void (*LogFunc)(const char* message);
typedef struct {
LogFunc log;
} ILogger;Bu arayüzü uygulamak için, LogFunc imzasıyla eşleşen gerçek fonksiyonlar yazarız, ardından bu fonksiyonların atandığı ILogger örnekleri oluştururuz:
void console_log(const char* message) {
printf("[CONSOLE] %s\n", message);
}
void file_log(const char* message) {
printf("[FILE] %s\n", message); // Dosya çıktısı simüle ediliyor
}
ILogger create_console_logger() {
ILogger logger = { console_log };
return logger;
}
ILogger create_file_logger() {
ILogger logger = { file_log };
return logger;
}Her bir "constructor" fonksiyonu, içine farklı bir fonksiyon bağlanmış bir ILogger döndürür. Bu logger'ları kullanan kodun, hangi uygulamayı aldığını bilmesine gerek yoktur:
void do_work(ILogger* logger) {
logger->log("Starting work...");
logger->log("Work complete!");
}
int main() {
ILogger console = create_console_logger();
ILogger file = create_file_logger();
do_work(&console); // console_log kullanır
do_work(&file); // file_log kullanır
return 0;
}do_work fonksiyonu, günlükleme (logging) uygulamasından tamamen ayrılmıştır. Çekirdek mantığın hiçbirini değiştirmeden günlükleyicileri özgürce değiştirebilirsiniz — bir arayüze (interface) göre programlamanın gücü budur.
Görev
KolayFarklı uygulamaların aynı arayüz sözleşmesini nasıl yerine getirebileceğini gösteren bir INotifier sistemi oluşturalım. Her ikisi de ortak bir arayüze uyan ancak farklı çıktılar üreten somut bildirimciler — bir EmailNotifier ve bir SMSNotifier — oluşturacaksınız.
Kodunuzu üç dosya halinde düzenleyeceksiniz:
notifier.h: Arayüzü burada tanımlayın. Birconst char*mesajı alan ve hiçbir şey döndürmeyenNotifyFuncadında bir fonksiyon işaretçisi türü oluşturun. Ardından, yalnızca bu türden birnotifyfonksiyon işaretçisi içeren birINotifierstruct'ı tanımlayın. Ayrıca, her biri değer olarak birINotifierdöndüren iki yapıcı (constructor) fonksiyon bildirin:create_email_notifiervecreate_sms_notifier.notifier.c: Somut bildirim fonksiyonlarını ve yapıcıları burada uygulayın. Şunları oluşturun:email_notify— mesajı şu formatta yazdırır:[EMAIL] messagesms_notify— mesajı şu formatta yazdırır:[SMS] messagecreate_email_notifier—email_notifyfonksiyonuna bağlı birINotifierdöndürürcreate_sms_notifier—sms_notifyfonksiyonuna bağlı birINotifierdöndürür
main.c: Her şeyi burada birleştirin. Bir bildirim türü ve bir mesaj okuyun, yapıcı fonksiyonları kullanarak uygun bildirimciyi oluşturun ve bildirimi arayüz üzerinden gönderin.
Programınız iki girdi alacaktır: bir bildirim türü (e-posta için 1, SMS için 2) ve gönderilecek bir mesaj.
Uygun bildirimciyi oluşturmak için yapıcı fonksiyonları kullanın, ardından mesajı görüntülemek için arayüz üzerinden notify fonksiyonunu çağırın.
Tür 1 ve mesaj Meeting at 3pm olduğunda örnek çıktı:
[EMAIL] Meeting at 3pmTür 2 ve mesaj Your code shipped olduğunda örnek çıktı:
[SMS] Your code shippedBu desenin gücü, main.c dosyasının her bir bildirimcinin dahili olarak nasıl çalıştığını bilmesine gerek duymamasıdır — sadece arayüzün notify fonksiyonunu çağırır ve doğru uygulama yürütülür. Başlık dosyanızda include guard kullanmayı unutmayın.
Kendin dene
#include <stdio.h>
#include "notifier.h"
int main() {
int type;
char message[256];
// Bildirim türünü oku (e-posta için 1, SMS için 2)
scanf("%d", &type);
getchar(); // yeni satır karakterini tüket
// Mesajı oku
fgets(message, sizeof(message), stdin);
// Eğer varsa sondaki yeni satır karakterini kaldır
int len = 0;
while (message[len] != '\0') len++;
if (len > 0 && message[len-1] == '\n') message[len-1] = '\0';
// TODO: Türe göre uygun notifier'ı oluştur
// Tip 1 için create_email_notifier() kullan
// Tip 2 için create_sms_notifier() kullan
// TODO: Arayüz üzerinden notify fonksiyonunu çağır
// notifier.notify(message);
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ı8Polimorfizm
Struct'larda Fonksiyon İşaretçileriMetotları Simüle EtmeArayüz KavramıArayüzleri UygulamaPolimorfik İterasyonÖzet: Greeter3Nesne 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