Menu
Coddy logo textTech

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.

challenge icon

Görev

Kolay

Farklı 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. Bir const char* mesajı alan ve hiçbir şey döndürmeyen NotifyFunc adında bir fonksiyon işaretçisi türü oluşturun. Ardından, yalnızca bu türden bir notify fonksiyon işaretçisi içeren bir INotifier struct'ı tanımlayın. Ayrıca, her biri değer olarak bir INotifier döndüren iki yapıcı (constructor) fonksiyon bildirin: create_email_notifier ve create_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] message
    • sms_notify — mesajı şu formatta yazdırır: [SMS] message
    • create_email_notifieremail_notify fonksiyonuna bağlı bir INotifier döndürür
    • create_sms_notifiersms_notify fonksiyonuna bağlı bir INotifier dö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 3pm

Tür 2 ve mesaj Your code shipped olduğunda örnek çıktı:

[SMS] Your code shipped

Bu 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;
}
quiz iconKendini test et

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