Menu
Coddy logo textTech

Adaptör Kalıbı

Coddy'nin C++ Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 97 / 104.

Adapter kalıbı, uyumsuz arayüzlerin birlikte çalışmasını sağlar. İki sınıf arasında köprü görevi görerek bir sınıfın arayüzünü istemcilerin beklediği arayüze dönüştürür. Bu, özellikle sisteminizin arayüzüyle uyuşmayan eski kodu veya üçüncü taraf kütüphaneleri entegre ederken kullanışlıdır.

İhtiyacınız olan işi yapan mevcut bir sınıfınız olduğunu, ancak arayüzünün kodunuzun beklediğiyle eşleşmediğini hayal edin. Taraflardan herhangi birini değiştirmek yerine, mevcut sınıfı saran ve çağrıları dönüştüren bir adaptör oluşturursunuz:

#include <iostream>
#include <string>

// Uyumsuz arayüze sahip mevcut sınıf
class LegacyPrinter {
public:
    void printMessage(const std::string& msg) {
        std::cout << "Legacy: " << msg << "\n";
    }
};

// İstemcinin beklediği hedef arayüz
class Printer {
public:
    virtual void print(const std::string& text) = 0;
    virtual ~Printer() = default;
};

// Adapter, LegacyPrinter'ı sarar ve Printer arayüzünü uygular
class PrinterAdapter : public Printer {
    LegacyPrinter& legacy;
public:
    PrinterAdapter(LegacyPrinter& lp) : legacy(lp) {}
    
    void print(const std::string& text) override {
        legacy.printMessage(text);  // Çağrıyı çevir
    }
};

int main() {
    LegacyPrinter oldPrinter;
    PrinterAdapter adapter(oldPrinter);
    
    // İstemci beklenen arayüzü kullanır
    adapter.print("Hello World");
}

Adaptör, LegacyPrinter öğesine bir referans tutar ve Printer arayüzünü uygular. print() çağrıldığında, işlemi printMessage() öğesine devreder. İstemci kodu, altında yatan eski uygulamayı bilmeden Printer arayüzüyle çalışır.

Mevcut bir sınıfı kullanmak istediğinizde ancak arabirimi ihtiyaçlarınızla eşleşmediğinde veya uyumsuz arabirimlere sahip sınıflarla birlikte çalışan yeniden kullanılabilir bir sınıf oluşturmanız gerektiğinde Adapter kullanın.

challenge icon

Görev

Kolay

Farklı ses kitaplıklarının arayüzlerini birbirine bağlayan bir Media Player Adapter sistemi oluşturalım. Eski bir ses kitaplığını modern bir medya oynatıcı uygulamasına entegre ettiğinizi düşünün: eski kitaplık kusursuz çalışıyor, ancak arayüzü oynatıcınızın beklediği arayüzle eşleşmiyor. Adapter kalıbının öne çıktığı yer tam olarak burasıdır.

Kodunuzu dört dosyaya düzenleyeceksiniz:

  • MediaPlayer.h: Modern medya oynatıcınızın beklediği hedef arayüzü tanımlayın.

    Aşağıdaki saf sanal yöntemlere sahip soyut bir MediaPlayer sınıfı oluşturun:

    • play(const std::string& filename): belirtilen dosyayı oynatır
    • stop(): oynatmayı durdurur
    • setVolume(int level): ses düzeyini ayarlar (0-100)

    Sanal bir yıkıcı ekleyin.

  • LegacyAudioLib.h: Uyumsuz bir arayüze sahip mevcut "eski" ses kitaplığını oluşturun.

    LegacyAudioLib sınıfınız, oynatıcınızın beklediğinden farklı çalışan eski bir kitaplığı temsil eder. Şunlara sahip olmalıdır:

    • loadAudio(const std::string& path): Legacy: Loading [path] yazdırır
    • startPlayback(): Legacy: Playback started yazdırır
    • stopPlayback(): Legacy: Playback stopped yazdırır
    • adjustVolume(double percentage): ondalık bir değer (0.0 ile 1.0 arası) alır ve Legacy: Volume set to [percentage] yazdırır (ondalık değeri gösterir)
  • AudioAdapter.h: İki arayüzü birbirine bağlayan adapter'ı oluşturun.

    AudioAdapter sınıfınız MediaPlayer sınıfından kalıtım almalı ve bir LegacyAudioLib nesnesine başvuru tutmalıdır. Adapter, modern arayüzden gelen çağrıları eski arayüze çevirir:

    • play(), eski kitaplık üzerinde hem loadAudio() hem de startPlayback() yöntemlerini çağırmalıdır
    • stop(), çağrıyı stopPlayback() yöntemine devretmelidir
    • setVolume() bir tamsayı (0-100) alır, ancak eski kitaplık ondalık bir değer (0.0-1.0) bekler; bu nedenle dönüştürmeniz gerekir
  • main.cpp: Adapter'ın çalışmasını gösterin.

    İki girdi okuyun:

    1. Oynatılacak bir dosya adı (dize)
    2. Bir ses düzeyi (tamsayı, 0-100)

    Bir LegacyAudioLib örneği ve onu saran bir AudioAdapter oluşturun. Ardından adapter'ı MediaPlayer arayüzü üzerinden (bir MediaPlayer işaretçisi olarak saklayarak) şu işlemler için kullanın:

    1. Ses düzeyini giriş değerine ayarlayın
    2. Girişteki dosya adını oynatın
    3. Oynatmayı durdurun

Örneğin, song.mp3 ve 75 girdileriyle:

Legacy: Volume set to 0.75
Legacy: Loading song.mp3
Legacy: Playback started
Legacy: Playback stopped

podcast.wav ve 50 girdileriyle:

Legacy: Volume set to 0.5
Legacy: Loading podcast.wav
Legacy: Playback started
Legacy: Playback stopped

İstemci kodunun tamamen MediaPlayer arayüzüyle çalıştığına dikkat edin. Altta gerçek işi bir eski kitaplığın yaptığından haberi yoktur. Adapter, tamsayı ses düzeyini ondalık değere dönüştürmek de dahil olmak üzere tüm çevirileri yönetir. Adapter kalıbının özü budur: taraflardan hiçbirini değiştirmeden uyumsuz arayüzlerin birlikte çalışmasını sağlamak.

Kendin dene

#include <iostream>
#include <string>
#include "MediaPlayer.h"
#include "LegacyAudioLib.h"
#include "AudioAdapter.h"

using namespace std;

int main() {
    // Girdileri oku
    string filename;
    int volumeLevel;
    cin >> filename;
    cin >> volumeLevel;
    
    // TODO: Bir LegacyAudioLib örneği oluştur
    
    // TODO: Eski kütüphaneyi saran bir AudioAdapter oluştur
    
    // TODO: Adaptörü bir MediaPlayer işaretçisi olarak sakla
    
    // TODO: MediaPlayer arayüzünü şunlar için kullan:
    // 1. Ses seviyesini girdi seviyesine ayarla
    // 2. Girdi dosya adını oynat
    // 3. Oynatmayı durdur
    
    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.

Nesne Yönelimli Programlama bölümündeki tüm dersler

Kendi başına pratik yap: Online C++ derleyicisi