Menu
CoddyTech

Pola Adapter

Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan Python di Coddy. Pelajaran 50 dari 64.

Adapter Pattern memungkinkan object dengan interface yang tidak kompatibel untuk bekerja bersama. Pola ini berfungsi sebagai jembatan dengan membungkus class yang sudah ada menggunakan interface baru yang diharapkan oleh client.

Berikut dua sistem dengan antarmuka yang tidak kompatibel:

class OldPrinter:
    def old_print(self, text):
        return f"OLD: {text}"

class NewPrinter:
    def print(self, text):
        return f"NEW: {text}"

Printer lama menggunakan old_print(), sedangkan printer baru menggunakan print().

Buat adapter agar printer lama berfungsi dengan antarmuka baru:

class PrinterAdapter:
    def __init__(self, old_printer):
        self.old_printer = old_printer
    
    def print(self, text):
        # Sesuaikan interface lama dengan interface baru
        return self.old_printer.old_print(text)

Adapter membungkus printer lama dan menyediakan antarmuka yang diharapkan.

Gunakan kedua printer dengan kode client yang sama:

def print_document(printer, text):
    return printer.print(text)  # Mengharapkan method print()

# Gunakan printer baru secara langsung
new_printer = NewPrinter()
print(print_document(new_printer, "Hello"))

# Gunakan printer lama melalui adapter
old_printer = OldPrinter()
adapter = PrinterAdapter(old_printer)
print(print_document(adapter, "Hello"))

Buat contoh lain dengan pemutar media:

class Mp3Player:
    def play_mp3(self, filename):
        return f"Playing MP3: {filename}"

class Mp4Player:
    def play_mp4(self, filename):
        return f"Playing MP4: {filename}"

class MediaAdapter:
    def __init__(self, player, audio_type):
        self.player = player
        self.audio_type = audio_type
    
    def play(self, filename):
        if self.audio_type == "mp3":
            return self.player.play_mp3(filename)
        elif self.audio_type == "mp4":
            return self.player.play_mp4(filename)
class AudioPlayer:
    def play(self, audio_type, filename):
        if audio_type == "mp3":
            return Mp3Player().play_mp3(filename)
        else:
            adapter = MediaAdapter(Mp4Player(), audio_type)
            return adapter.play(filename)

player = AudioPlayer()
print(player.play("mp3", "song.mp3"))
print(player.play("mp4", "video.mp4"))

Output:

NEW: Hello
OLD: Hello
Playing MP3: song.mp3
Playing MP4: video.mp4

Poin Utama: Pola Adapter membuat antarmuka yang tidak kompatibel dapat bekerja bersama dengan membungkus class yang sudah ada menggunakan antarmuka baru. Adapter menerjemahkan pemanggilan dari antarmuka yang diharapkan ke antarmuka sebenarnya dari object yang dibungkus. Ini berguna untuk mengintegrasikan kode lama atau library pihak ketiga tanpa mengubah kode yang sudah ada.

challenge icon

Tantangan

Sedang

Dalam tantangan ini, kamu akan menerapkan pola desain Adapter untuk mengintegrasikan sistem lama dengan arsitektur aplikasi modern. Pola Adapter memungkinkan object dengan antarmuka yang tidak kompatibel untuk bekerja bersama dengan membuat pembungkus (adapter) yang menerjemahkan satu antarmuka ke antarmuka lain.

 

Perusahaanmu memiliki sistem analisis dan visualisasi data lama yang perlu diintegrasikan dengan platform analitik modern yang baru. Komponen lama memiliki antarmuka yang tidak kompatibel dengan sistem baru. Daripada menulis ulang kode lama, yang berisiko dan mahal, kamu ditugaskan untuk membuat adapter agar komponen ini dapat bekerja dengan sistem baru.

Kamu perlu:

  1. Memahami antarmuka modern yang didefinisikan dalam interfaces.py (file ini tidak dapat dimodifikasi)
  2. Memeriksa komponen lama di legacy_system.py (file ini tidak dapat dimodifikasi)
  3. Menerapkan class adapter di adapters.py agar komponen lama kompatibel dengan antarmuka modern
  4. Membuat sistem modern di modern_system.py yang menggunakan antarmuka ini

Coba sendiri

# Impor semua class yang diperlukan
from adapters import LegacyDataAnalyzerAdapter, LegacyChartGeneratorAdapter
from modern_system import AnalyticsSystem

# Penangan kasus uji yang menyeluruh
test_case = input()

if test_case == "basic_adapter_test":
    # Uji fungsi dasar adapter
    processor = LegacyDataAnalyzerAdapter()
    data = [1, 2, 3, 4, 5]
    processor.process_data(data)
    results = processor.get_results()
    print(f"Results: {results}")

elif test_case == "visualizer_adapter_test":
    # Uji adapter visualizer
    visualizer = LegacyChartGeneratorAdapter("bar")
    data = [10, 20, 30, 40, 50]
    success = visualizer.visualize(data)
    if success:
        export_success = visualizer.export_visualization("test_chart.png")
        print(f"Visualization exported: {export_success}")

elif test_case == "analytics_system_test":
    # Uji sistem analitik secara menyeluruh
    processor = LegacyDataAnalyzerAdapter()
    visualizer = LegacyChartGeneratorAdapter("line")
    system = AnalyticsSystem(processor, visualizer)
    
    data = [15, 25, 35, 45, 55]
    result = system.analyze_and_visualize(data, "analytics_output.png")
    print(f"System result: {result}")

elif test_case == "validation_error_test":
    # Uji error validasi
    processor = LegacyDataAnalyzerAdapter()
    try:
        processor.process_data("invalid_data")
        print("Validation failed - should have raised ValueError")
    except ValueError as e:
        print(f"Validation error caught: {e}")

elif test_case == "empty_data_test":
    # Uji dengan data kosong
    processor = LegacyDataAnalyzerAdapter()
    try:
        processor.process_data([])
        results = processor.get_results()
        print(f"Empty data results: {results}")
    except Exception as e:
        print(f"Empty data error: {e}")

elif test_case == "chart_types_test":
    # Uji berbagai jenis grafik
    chart_types = ["bar", "line", "pie"]
    data = [5, 15, 25, 35]
    
    for chart_type in chart_types:
        visualizer = LegacyChartGeneratorAdapter(chart_type)
        success = visualizer.visualize(data)
        print(f"{chart_type} chart created: {success}")

elif test_case == "file_extension_test":
    # Uji penanganan ekstensi file
    visualizer = LegacyChartGeneratorAdapter()
    data = [1, 2, 3, 4]
    visualizer.visualize(data)
    
    # Uji berbagai format nama file
    filenames = ["test", "test.jpg", "test.pdf", "test.png"]
    for filename in filenames:
        success = visualizer.export_visualization(filename)
        print(f"Export '{filename}': {success}")

elif test_case == "summary_test":
    # Uji ringkasan analisis
    processor = LegacyDataAnalyzerAdapter()
    visualizer = LegacyChartGeneratorAdapter()
    system = AnalyticsSystem(processor, visualizer)
    
    data = [10, 20, 30, 40, 50, 60]
    system.analyze_and_visualize(data)
    summary = system.get_analysis_summary()
    print("Analysis Summary:")
    print(summary)

elif test_case == "mixed_data_test":
    # Uji dengan data numerik campuran
    processor = LegacyDataAnalyzerAdapter()
    data = [1.5, 2, 3.7, 4, 5.2]
    processor.process_data(data)
    results = processor.get_results()
    print(f"Mixed data results: {results}")

elif test_case == "invalid_numeric_test":
    # Uji dengan data numerik yang tidak valid
    processor = LegacyDataAnalyzerAdapter()
    try:
        processor.process_data([1, 2, "three", 4, 5])
        print("Validation failed - should have raised ValueError")
    except ValueError as e:
        print(f"Invalid numeric data error: {e}")

elif test_case == "no_results_summary_test":
    # Uji ringkasan tanpa hasil
    processor = LegacyDataAnalyzerAdapter()
    visualizer = LegacyChartGeneratorAdapter()
    system = AnalyticsSystem(processor, visualizer)
    
    summary = system.get_analysis_summary()
    print(f"No results summary: {summary}")

elif test_case == "large_dataset_test":
    # Uji dengan kumpulan data yang lebih besar
    processor = LegacyDataAnalyzerAdapter()
    data = list(range(1, 101))  # 1 sampai 100
    processor.process_data(data)
    results = processor.get_results()
    print(f"Large dataset - Mean: {results.get('mean', 'N/A'):.2f}")
    print(f"Large dataset - Min: {results.get('min', 'N/A')}")
    print(f"Large dataset - Max: {results.get('max', 'N/A')}")

elif test_case == "complete_workflow_test":
    # Uji alur kerja lengkap dengan beberapa operasi
    processor = LegacyDataAnalyzerAdapter()
    bar_visualizer = LegacyChartGeneratorAdapter("bar")
    line_visualizer = LegacyChartGeneratorAdapter("line")
    
    data = [12, 18, 25, 32, 28, 35, 42]
    
    # Buat sistem analitik dengan visualizer yang berbeda
    bar_system = AnalyticsSystem(processor, bar_visualizer)
    line_system = AnalyticsSystem(LegacyDataAnalyzerAdapter(), line_visualizer)
    
    # Jalankan analisis
    bar_result = bar_system.analyze_and_visualize(data, "bar_chart.png")
    line_result = line_system.analyze_and_visualize(data, "line_chart.png")
    
    print("Complete workflow test completed")
    print(f"Bar chart result: {bar_result['visualization_file']}")
    print(f"Line chart result: {line_result['visualization_file']}")
    
    # Ambil ringkasan
    print("Bar system summary:")
    print(bar_system.get_analysis_summary())
    print("Line system summary:")
    print(line_system.get_analysis_summary())
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Objek

Latihan sendiri: Compiler Python online