Pola Desain Dekorator Python vs Dekorator: Perbedaan Utama
Bandingkan dekorator Python dan pola desain dekorator klasik. Pahami perbedaan antara pembungkusan fungsi waktu definisi dan komposisi objek dinamis waktu proses dengan kode yang dapat dijalankan.
Meskipun dekorator Python dan pola desain dekorator memiliki nama yang sama dan konsep umum kode "membungkus" untuk memperluas perilaku, keduanya mewakili konstruksi dan filosofi yang sangat berbeda dalam pemrograman.
Dekorator Python adalah fitur bahasa—gula sintaksis yang memungkinkan Anda menggabungkan fungsi, metode, atau kelas pada waktu definisi. Ini adalah bentuk metaprogramming yang dijalankan ketika modul diimpor atau didefinisikan, mengubah cara fungsi tersebut berperilaku selama aplikasi dijalankan.
Pola Desain Dekorator, awalnya didefinisikan oleh Gang of Four (GoF), adalah pola desain struktural berorientasi objek. Hal ini dirancang untuk menambahkan tanggung jawab ke objek individual secara dinamis saat runtime, tanpa mempengaruhi objek lain dari kelas yang sama, dengan menggunakan kelas wrapper dan komposisi dinamis.
Matriks Perbandingan Fitur
| Feature | Python | Other Language |
|---|---|---|
| Konsep Inti | Gula sintaksis tingkat bahasa untuk membungkus fungsi/kelas. | Pola desain untuk menambahkan perilaku secara dinamis ke objek individual. |
| Waktu Eksekusi | Waktu definisi (berjalan satu kali saat modul dimuat). | Runtime (digunakan secara dinamis selama eksekusi program). |
| Entitas Sasaran | Fungsi, metode, atau seluruh kelas (lingkup statis). | Contoh objek tertentu (lingkup dinamis). |
| Metode Implementasi | Penutupan dan fungsi pembantu menggunakan sintaks `@decorator`. | Warisan kelas, penyelarasan antarmuka, dan komposisi objek. |
Syntax & Idiom Comparisons
01.Dekorator Python: Pembungkus Fungsi (Definisi-Waktu)
Dekorator Python memanfaatkan fungsi kelas satu untuk mencegat panggilan. Saat Anda menulis `@my_decorator`, Python meneruskan fungsi yang dihias ke fungsi dekorator Anda dan mengikat fungsi wrapper yang dikembalikan ke nama fungsi asli.
Dalam contoh ini, dekorator `@log_call` menggabungkan fungsi sederhana untuk melacak kapan fungsi tersebut dijalankan dan apa yang dikembalikannya. Perhatikan bahwa pembungkusan ini ditetapkan pada saat fungsinya ditentukan.
def log_call(func):
def wrapper(*args, **kwargs):
print(f"[LOG] Executing '{func.__name__}' with args {args}")
result = func(*args, **kwargs)
print(f"[LOG] '{func.__name__}' returned: {result}")
return result
return wrapper
@log_call
def add(a, b):
return a + b
# The wrapping occurs once at definition time
print("Result of add(5, 7):", add(5, 7))// Decorators in Python are syntactic sugar for function wrappers:
// add = log_call(add)
// They exist primarily to avoid duplicate boilerplate for logging, timing, and auth.02.Pola Desain Dekorator: Pembungkus Objek (Komposisi Runtime)
Pola Desain Dekorator klasik menggunakan komposisi kelas. Anda memiliki kelas komponen dasar, dan kelas dekorator yang membungkus komponen dasar ini. Saat runtime, Anda menyatukan konstruktor ini untuk membangun objek yang disesuaikan secara dinamis.
Di sini, kami menerapkan sistem dekorator Kopi klasik. Kita dapat membungkus objek dasar Coffee di dalam MilkDecorator, dan membungkusnya di dalam SugarDecorator, menghitung biaya akhir secara dinamis saat runtime.
class Coffee:
def get_cost(self):
return 5.0
def get_description(self):
return "Simple Coffee"
class MilkDecorator:
def __init__(self, coffee):
self.coffee = coffee
def get_cost(self):
return self.coffee.get_cost() + 1.5
def get_description(self):
return self.coffee.get_description() + ", Milk"
class SugarDecorator:
def __init__(self, coffee):
self.coffee = coffee
def get_cost(self):
return self.coffee.get_cost() + 0.5
def get_description(self):
return self.coffee.get_description() + ", Sugar"
# Chaining wrappers dynamically at runtime
my_drink = Coffee()
my_drink = MilkDecorator(my_drink)
my_drink = SugarDecorator(my_drink)
print("Drink description:", my_drink.get_description())
print("Total Cost: $", my_drink.get_cost())// Standard OO languages (like Java) require shared interfaces:
// interface Coffee { double getCost(); }
// class SimpleCoffee implements Coffee { ... }
// class MilkDecorator implements Coffee { ... }
// Python's duck typing allows dynamic composition without interfaces.Putusan & Ringkasan
Gunakan dekorator Python (@decorator) ketika Anda ingin menerapkan masalah lintas sektoral (seperti logging, pengaturan waktu, autentikasi, cache, atau validasi input) ke fungsi atau rute secara seragam di seluruh aplikasi Anda.
Gunakan Pola Desain Dekorator saat Anda perlu melampirkan atau melepaskan perilaku dari masing-masing instance objek secara dinamis saat runtime, terutama saat menggabungkan beberapa kelas wrapper opsional dalam urutan arbitrer.
Pertanyaan yang Sering Diajukan
Mengapa halaman Wikipedia mengatakan dekorator Python bukan pola dekorator?
Karena dekorator Python standar membungkus fungsi dan definisi kelas pada waktu kompilasi/definisi, sehingga memengaruhi semua instance fungsi tersebut. Pola desain klasik membungkus instance objek individual secara dinamis saat runtime.
Apakah Pola Dekorator GoF berguna dengan Python?
Ya, tapi pengetikan bebek Python membuatnya lebih mudah untuk diterapkan dibandingkan dengan bahasa yang diketik secara statis seperti Java atau C++, karena dekorator tidak perlu mewarisi dari antarmuka dasar formal.
Perbandingan Lainnya
Sumber Daya Python yang Direkomendasikan
Perluas pengetahuan Anda dengan tutorial interaktif terkait, lembar contekan, dan perbandingan kode.
Dekorator Python
Pelajari dekorator Python untuk mengubah perilaku fungsi secara dinamis. Pahami fungsi wrapper, @ sintaksis, dan argumen penanganan di dekorator.
Cara Membuat dan Menggunakan Dekorator dengan Python
Pelajari cara menulis dan menerapkan dekorator dengan Python. Menguasai fungsi pembungkusan, mengubah perilaku, menangani argumen, dan melestarikan metadata dengan pembungkus.
Lembar
Panduan referensi untuk ekspresi reguler Python. Pelajari pola pencocokan, pencarian, temukan semua, sub, dan ekspresi reguler penting.