Menu
Coddy logo textTech

Wzorzec adaptera

Część sekcji Programowanie obiektowe ścieżki Java w Coddy. Lekcja 71 z 87.

Wzorzec adaptera to strukturalny wzorzec projektowy, który umożliwia współpracę niezgodnych interfejsów. Działa jak pomost między dwiema klasami, przekształcając interfejs jednej klasy w interfejs, którego oczekuje klient. Pomyśl o nim jak o adapterze zasilania, który pozwala podłączyć europejskie urządzenie do amerykańskiego gniazdka.

Wyobraź sobie, że masz istniejący interfejs MediaPlayer, który odtwarza pliki audio, ale musisz zintegrować bibliotekę innej firmy, która używa zupełnie innego interfejsu do odtwarzania filmów:

// Istniejący interfejs używany przez twój kod
interface MediaPlayer {
    void play(String filename);
}

// Klasa zewnętrzna z niezgodnym interfejsem
class AdvancedVideoPlayer {
    public void playVideo(String filename) {
        System.out.println("Playing video: " + filename);
    }
}

Adapter opakowuje niekompatybilną klasę i implementuje oczekiwany interfejs, tłumacząc wywołania między nimi:

class VideoPlayerAdapter implements MediaPlayer {
    private AdvancedVideoPlayer videoPlayer;
    
    public VideoPlayerAdapter() {
        this.videoPlayer = new AdvancedVideoPlayer();
    }
    
    public void play(String filename) {
        videoPlayer.playVideo(filename);
    }
}

Teraz Twój kod kliencki może korzystać z odtwarzacza wideo za pośrednictwem znanego interfejsu MediaPlayer:

MediaPlayer player = new VideoPlayerAdapter();
player.play("movie.mp4");  // Wynik: Odtwarzanie wideo: movie.mp4

Wzorzec Adapter jest nieoceniony przy integrowaniu starszego kodu lub bibliotek innych firm bez modyfikowania ich kodu źródłowego. Klient nie wie, że współpracuje z klasą-adapterem. Po prostu korzysta ze znanego mu interfejsu.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system konwersji temperatury, korzystając ze wzorca Adapter! Masz istniejącą aplikację pogodową, która obsługuje temperatury w stopniach Celsjusza, ale musisz zintegrować starszy czujnik temperatury, który podaje odczyty wyłącznie w stopniach Fahrenheita. Zamiast modyfikować którykolwiek z systemów, utworzysz adapter, który połączy je ze sobą.

Rozmieścisz swój kod w czterech plikach:

  • TemperatureProvider.java: Zdefiniuj interfejs, którego oczekuje Twoja aplikacja pogodowa. Powinien deklarować metodę getTemperatureCelsius(), która zwraca wartość typu double reprezentującą temperaturę w stopniach Celsjusza.
  • FahrenheitSensor.java: Ta klasa reprezentuje starszy czujnik z niezgodnym interfejsem. Utwórz klasę z prywatnym polem typu double przechowującym temperaturę w stopniach Fahrenheita, ustawianym przez konstruktor. Klasa powinna mieć metodę readFahrenheit(), która zwraca zapisaną wartość temperatury w stopniach Fahrenheita.
  • SensorAdapter.java: Utwórz adapter, który dostosuje czujnik Fahrenheita do współpracy z Twoją aplikacją pogodową. Adapter powinien implementować interfejs TemperatureProvider i opakowywać obiekt FahrenheitSensor. Po wywołaniu metody getTemperatureCelsius() powinien odczytać wartość z czujnika i przeliczyć ją na stopnie Celsjusza za pomocą wzoru: (fahrenheit - 32) * 5 / 9.
  • Main.java: Połącz wszystko w całość! Otrzymasz jedno wejście: odczyt temperatury w stopniach Fahrenheita (double).

    Utwórz obiekt FahrenheitSensor z wartością wejściową. Następnie utwórz obiekt SensorAdapter, który opakowuje ten czujnik. Przypisz adapter do zmiennej typu TemperatureProvider, aby pokazać, że Twoja aplikacja pogodowa może z niego korzystać za pośrednictwem oczekiwanego interfejsu.

    Wypisz wynik w tym formacie: Temperature: [celsius] C, gdzie wartość celsius jest sformatowana do jednego miejsca po przecinku.

Otrzymasz jedno wejście: temperaturę w stopniach Fahrenheita (double).

Na przykład dla wejścia 98.6 wynikiem będzie:

Temperature: 37.0 C

Zwróć uwagę, że Twoja klasa Main korzysta wyłącznie z interfejsu TemperatureProvider. Nie wie, że rzeczywista temperatura pochodzi z czujnika Fahrenheita, dostosowanego w tle. Na tym polega elegancja wzorca Adapter!

Spróbuj swoich sił

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        double fahrenheit = scanner.nextDouble();
        
        // TODO: Utwórz FahrenheitSensor z podaną wartością wejściową
        
        // TODO: Utwórz SensorAdapter, który opakowuje czujnik
        
        // TODO: Zapisz adapter w zmiennej typu TemperatureProvider
        
        // TODO: Pobierz temperaturę w stopniach Celsjusza i ją wypisz
        // Format: "Temperature: [celsius] C" z jednym miejscem po przecinku
        // Wskazówka: Użyj String.format("%.1f", value) do formatowania
    }
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Java online