Menu
CoddyTech

Pola Perintah

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

Pola Command membungkus permintaan sebagai object, sehingga kamu dapat mengantrekan operasi, mencatat permintaan, dan mendukung fungsi pembatalan. Pola ini memisahkan object yang memanggil operasi dari object yang menjalankannya.

Berikut adalah class perintah sederhana:

class Command:
    def execute(self):
        pass

class LightOnCommand(Command):
    def __init__(self, light):
        self.light = light
    
    def execute(self):
        self.light.turn_on()

class LightOffCommand(Command):
    def __init__(self, light):
        self.light = light
    
    def execute(self):
        self.light.turn_off()

Setiap perintah mengenkapsulasi operasi tertentu pada object penerima.

Buat receiver yang melakukan pekerjaan sebenarnya:

class Light:
    def turn_on(self):
        print("Light is on")
    
    def turn_off(self):
        print("Light is off")

Buat invoker yang menjalankan perintah:

class RemoteControl:
    def __init__(self):
        self.command = None
    
    def set_command(self, command):
        self.command = command
    
    def press_button(self):
        self.command.execute()

Gunakan pola perintah:

# Buat penerima
light = Light()

# Buat perintah
light_on = LightOnCommand(light)
light_off = LightOffCommand(light)

# Buat pemanggil
remote = RemoteControl()

# Jalankan perintah yang berbeda
remote.set_command(light_on)
remote.press_button()

remote.set_command(light_off)
remote.press_button()

Tambahkan dukungan untuk operasi pembatalan:

class UndoableCommand(Command):
    def undo(self):
        pass

class LightOnCommand(UndoableCommand):
    def __init__(self, light):
        self.light = light
    
    def execute(self):
        self.light.turn_on()
    
    def undo(self):
        self.light.turn_off()

class SmartRemote:
    def __init__(self):
        self.last_command = None
    
    def execute_command(self, command):
        command.execute()
        self.last_command = command
    
    def undo(self):
        if self.last_command:
            self.last_command.undo()

smart_remote = SmartRemote()
smart_remote.execute_command(LightOnCommand(light))
smart_remote.undo()  # Mematikan lampu

Output:

Light is on
Light is off
Light is on
Light is off

Poin Utama: Command Pattern mengubah permintaan menjadi object yang dapat disimpan, diteruskan, dan dijalankan nanti. Pemanggil tidak perlu tahu cara melakukan operasi, cukup memanggil execute() pada object perintah. Ini memungkinkan fitur seperti undo/redo, mengantrekan operasi, dan mencatat perintah.

challenge icon

Tantangan

Mudah

Dalam tantangan ini, kamu akan mengimplementasikan class dasar Command yang menjadi fondasi di command.py, komponen penting dari Command Pattern. Latihan ini berfokus secara khusus pada enkapsulasi: menyimpan data secara privat dan mengeksposnya dengan aman melalui property.

Ubah hanya command.py sesuai komentar TODO. Komentar TODO akan memandu kamu untuk:

  • Menyimpan nama perintah sebagai atribut privat (_name)
  • Mengeksposnya melalui property hanya-baca (name)
  • Mengimplementasikan method display_info() yang mencetak nama perintah

Catatan: Tantangan ini hanya membahas class dasar Command. Invoker, Receiver, dan fungsi undo akan diperkenalkan di pelajaran berikutnya. Dengan menyelesaikan langkah ini, kamu mendapatkan fondasi enkapsulasi yang menjadi dasar pola lengkapnya.

Implementasimu akan diuji oleh driver.py, yang memvalidasi:

  • Fungsi dasar dan format output
  • Kasus tepi (input kosong, karakter khusus, nama panjang)
  • Perlindungan property hanya-baca (percobaan menjalankan obj.name = ... seharusnya memunculkan AttributeError)
  • Keberadaan atribut privat _name

Coba sendiri

# Impor class Command dari command.py
from command import Command

# Penangan kasus uji yang menyeluruh
test_case = input()

if test_case == "basic_test":
    obj = Command("Test Name")
    obj.display_info()
elif test_case == "validation_test":
    obj = Command("Validation Test")
    print(f"Name: {obj.name}")
elif test_case == "empty_name_test":
    obj = Command("")
    obj.display_info()
    print(f"Empty name handled: {'Yes' if obj.name == '' else 'No'}")
elif test_case == "property_access_test":
    obj = Command("Property Test")
    original_name = obj.name
    try:
        # Ini seharusnya gagal karena name adalah property yang hanya bisa dibaca
        obj.name = "Modified Name"
        print("Property protection failed")
    except AttributeError:
        print("Property protected successfully")
    print(f"Name unchanged: {obj.name == original_name}")
elif test_case == "multiple_commands_test":
    commands = [
        Command("First Command"),
        Command("Second Command"),
        Command("Third Command")
    ]
    for cmd in commands:
        cmd.display_info()
elif test_case == "attribute_test":
    obj = Command("Attribute Test")
    has_private_name = hasattr(obj, "_name")
    print(f"Has _name attribute: {has_private_name}")
elif test_case == "special_chars_test":
    obj = Command("!@#$%^&*()_+{}[]|\\:;\"'<>,.?/")
    obj.display_info()
elif test_case == "long_name_test":
    long_name = "A" * 100
    obj = Command(long_name)
    obj.display_info()
    print(f"Name length: {len(obj.name)}")
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