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.mp4Poin 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.
Tantangan
SedangDalam 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:
- Memahami antarmuka modern yang didefinisikan dalam
interfaces.py(file ini tidak dapat dimodifikasi) - Memeriksa komponen lama di
legacy_system.py(file ini tidak dapat dimodifikasi) - Menerapkan class adapter di
adapters.pyagar komponen lama kompatibel dengan antarmuka modern - Membuat sistem modern di
modern_system.pyyang 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())Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Objek
1Dasar-Dasar OOP
File EksternalPengantar OOPclass vs objectParameter selfmethodAtributMethod Konstruktor (__init__)Rangkuman: Kalkulator Sederhana4Pewarisan
Pewarisan DasarFungsi super()Penimpaan MethodPewarisan BergandaUrutan Resolusi MethodRingkasan: Hierarki Karyawan5Polimorfisme
Meninjau Ulang Method OverridingDuck Typingclass dan method AbstrakDesain InterfaceRingkasan: Kalkulator Bentuk8Konsep OOP Lanjutan
Komposisi vs PewarisanMixinsMetode Statis dan Metode ClassDecorator ClassPengelola Konteks11Pola Desain Bagian 2
Pola PerintahPola AdapterPola DecoratorPola Template MethodPola StatePola Composite3Property class
Variabel instance vs variabel classDekorator propertyAtribut privatRangkuman: Pengelola Rekening Bank6Enkapsulasi
Anggota Public, Protected, PrivateModifier AksesPenyembunyian InformasiDecorator Property Tingkat LanjutUlasan: Sistem Catatan Siswa12Proyek: Manajemen Perpustakaan
Ikhtisar Proyekclass Buku dan PenggunaSistem PeminjamanFitur PencarianAntarmuka AdminPengujian dan IntegrasiLatihan sendiri: Compiler Python online