Menu
Coddy logo textTech

Durum Kalıbı

Coddy'nin Python Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 53 / 64.

State Pattern, bir nesnenin dahili durumu değiştiğinde davranışını değiştirmesine olanak tanır. Nesne, mevcut durumuna göre sınıfını değiştiriyormuş gibi görünür.

İşte bir trafik ışığı için basit durum sınıfları:

class RedState:
    def next_state(self, light):
        print("Red -> Green")
        light.state = GreenState()
    
    def current_color(self):
        return "Red"

class GreenState:
    def next_state(self, light):
        print("Green -> Yellow")
        light.state = YellowState()
    
    def current_color(self):
        return "Green"

class YellowState:
    def next_state(self, light):
        print("Yellow -> Red")
        light.state = RedState()
    
    def current_color(self):
        return "Yellow"

Her durum, bir sonraki duruma geçiş yapılırken ne olacağını tanımlar.

Mevcut durumu tutan bir bağlam sınıfı oluşturun:

class TrafficLight:
    def __init__(self):
        self.state = RedState()  # Kırmızı ile başla
    
    def change(self):
        self.state.next_state(self)
    
    def get_color(self):
        return self.state.current_color()

Trafik lambası davranışı mevcut durum nesnesine devreder.

Trafik ışığını kullanın:

light = TrafficLight()
print(f"Current: {light.get_color()}")

light.change()  # Kırmızı -> Yeşil
print(f"Current: {light.get_color()}")

light.change()  # Yeşil -> Sarı
print(f"Current: {light.get_color()}")

light.change()  # Sarı -> Kırmızı
print(f"Current: {light.get_color()}")

Basit bir oynatıcıyla başka bir örnek oluşturalım:

class PlayingState:
    def play(self, player):
        print("Already playing")
    
    def stop(self, player):
        print("Stopping music")
        player.state = StoppedState()

class StoppedState:
    def play(self, player):
        print("Starting music")
        player.state = PlayingState()
    
    def stop(self, player):
        print("Already stopped")

class MusicPlayer:
    def __init__(self):
        self.state = StoppedState()
    
    def play(self):
        self.state.play(self)
    
    def stop(self):
        self.state.stop(self)

player = MusicPlayer()
player.play()   # Müzik başlatılıyor
player.play()   # Zaten çalıyor
player.stop()   # Müzik durduruluyor
player.stop()   # Zaten durmuş

Çıktı:

Current: Red
Red -> Green
Current: Green
Green -> Yellow
Current: Yellow
Yellow -> Red
Current: Red
Starting music
Already playing
Stopping music
Already stopped

Temel Nokta: State Pattern, duruma özgü davranışı ayrı sınıflarda kapsüller ve context nesnesinin işlemleri mevcut duruma devretmesini sağlar. Durum değiştiğinde davranış da otomatik olarak değişir. Bu, karmaşık if/else ifadelerini ortadan kaldırır ve yeni durumlar eklemeyi kolaylaştırır.

challenge icon

Görev

Kolay

Tek düğmeli bir lamba için state.py dosyasında State desenini uygulayın. Her basış, lambayı bir döngü içinde üç durumdan geçirir: kapalı, düşük, yüksek ve tekrar kapalı. Bir dize üzerinde if zinciri kullanmak yerine her durum, düğmeye basıldığında ne olacağını bilen kendi nesnesidir.

  • LampState, press(lamp) ve describe() metotlarına sahip temel sınıftır.
  • OffState, LowState ve HighState bu metotları uygular: press, sonraki durumla (kapalıdan düşüğe, düşükten yükseğe, yüksekten kapalıya) birlikte lamp.set_state(...) çağrısını yapar ve describe, Lamp is off, Lamp is on low veya Lamp is on high döndürür.
  • Lamp bağlamdır: OffState durumunda başlar, set_state durum nesnesini değiştirir, press_button çağrıyı mevcut duruma devreder ve status mevcut açıklamayı döndürür.

driver.py kilitlidir: düğmeye basar ve durumu yazdırır. Lamp'ın hangi durumda olduğunu hiçbir zaman kontrol etmediğine dikkat edin; buna durum nesneleri karar verir.

Kendin dene

from state import Lamp

# Test durumu işleyicisi (değiştirmeyin)
test_case = input()
lamp = Lamp()

if test_case == "initial_test":
    print(lamp.status())
elif test_case == "one_press_test":
    lamp.press_button()
    print(lamp.status())
elif test_case == "cycle_test":
    for _ in range(4):
        print(lamp.status())
        lamp.press_button()
elif test_case == "many_presses_test":
    for _ in range(7):
        lamp.press_button()
    print(lamp.status())
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler

Kendi başına pratik yap: Online Python derleyicisi