Blog

Elle Durum Makinesi Kodu Yazmak Neden Kötü Bir Fikir?

Yayınlanma tarihi 2026-05-26

Elle Durum Makinesi Kodu Yazmak Neden Kötü Bir Fikir?

Gömülü yazılım projelerinde en kritik ve en karmaşık mantık genellikle bir durum makinesinde yaşar. Motor kontrolcüsü, iletişim protokolü, kullanıcı arayüzü akışı, güç yönetimi — bunların hepsi "şu anda hangi durumdayım ve hangi olaya nasıl tepki veririm?" sorusuna cevap verir.

Ve çoğu ekip bu soruyu aynı şekilde yanıtlar: switch/case blokları, enum tanımları, durum değişkenleri, if zincirleri. Çalışır. Bir süre.


Tanıdık Bir Senaryo

Bir araç kapı kontrolcüsü düşünün. İlk sürümde dört durum var: Açık, Kapanıyor, Kapalıö Açılıyor. Kod 200 satır, okunabilir, test edilebilir.

Altı ay sonra gereksinimler değişir:

  • Otomatik mod eklendi — kapı belirli süre sonra kendiliğinden kapanmalı
  • Manuel mod eklendi — kullanıcı otomatik davranışı devre dışı bırakabilmeli
  • İki mod arasında geçiş çalışma sırasında yapılabilmeli
  • Güç kesintisinde son durum hatırlanmalı
  • Yeni sensör eklendi — tam açık ve tam kapalı pozisyonlar ayrı ayrı algılanmalı

Kod artık 800 satır. Her switch bloğu her durumu kontrol ediyor. Mod değişkeni isAutomatic her koşulda kontrol ediliyor. Yeni bir geliştirici kodu anlamak için bir hafta harcıyor.

Bu, durum patlaması (state explosion) — elle yazılan durum makinelerinin kaçınılmaz sonu.


Gerçek Maliyetler

Elle yazılmış durum makinesi kodunun maliyeti genellikle doğru ölçülmez çünkü birikir.

Bakım maliyeti. Yeni bir durum veya geçiş eklendiğinde tüm switch bloklarına dokunmak gerekir. Bir yeri değiştirip diğerini unutmak kolaydır. Derleyici bunu yakalamaz.

Test maliyeti. Her durum-olay kombinasyonu test edilmeli. 10 durum × 10 olay = 100 test senaryosu. Bunları elle yazmak ve güncel tutmak ciddi emek ister. Çoğu projede bu yapılmaz.

Onboarding maliyeti. Yeni bir geliştirici koda ilk baktığında modeli yok — sadece kod var. Tasarım niyetini kodu okuyarak çıkarmak zorunda kalır. Genellikle tam anlayamaz ve var olan mantığın etrafından dolaşır.

Senkronizasyon maliyeti. Tasarım dokümanı varsa bile kodla senkronize tutmak ayrı bir iş yüküdür. Çoğu projede zaman içinde birbirinden kopar.


Sorunun Kökü

Problem switch/case kullanmak değil. Problem şu: model ve implementasyon ayrı yaşıyor.

Tasarımcı bir diyagram çizer. Geliştirici bu diyagramı koda çevirir. İkisi arasında otomatik bir bağ yoktur. Diyagram değişir, kod değişir — ama birbirinden bağımsız.

Hiyerarşik durum makinelerinde bu daha da ağırlaşır. İç içe geçmiş durumlar, geçmişi hatırlayan pseudostate'ler, paralel çalışan bölgeler — bunları C++ switch/case ile doğru modellemek hem zor hem de hataya açıktır.


Model Tabanlı Yaklaşımın Farkı

UMTSM bu soruna farklı bir yerden yaklaşır: modeli ve kodu aynı kaynaktan türet.

Geliştirici .umt dosyasında durum makinesini tanımlar. Bu tanımdan:

  • C/C++ durum makinesi iskeleti otomatik üretilir
  • Test fixture ve mock'lar otomatik üretilir
  • CMake build konfigürasyonu otomatik üretilir

Model değiştiğinde üretilen kod değişir. Kullanıcı implementasyonları (aksiyon kodları) korunur. Tasarım ile implementasyon hiçbir zaman birbirinden kopmaz.

Kapı kontrolcüsü örneğinde — beş gereksinim değişikliğinin tamamı .umt dosyasına yansıtıldı:

persistent deep history -> ManualMode_Open;

state AutomaticMode
{
    state Open
    {
        entry / resetWaitingTime;
        do    / wait;                 // ← zamanlayıcı thread'i
        -> Closing;                   // ← süre dolunca otomatik geçiş

        Manual -> ManualMode:Open;    // ← tek satır mod geçişi
    }
}

Bu yedi satır şunları ifade ediyor:

  • Open durumuna girildiğinde zamanlayıcı sıfırlanır
  • do / wait thread olarak çalışır, süre dolunca tamamlanır
  • Tamamlandığında Closing'e geçilir
  • Manual eventi geldiğinde ManualMode'a geçilir

Üretilen C++ kodu bu semantiği doğru ve deterministik biçimde uygular — mutex koruması, thread yönetimi, tarih geri yükleme dahil.


"Ama Biz Zaten Çalışan Bir Kodumuz Var"

Çoğu proje bu noktada "geçiş yapmaya değmez" der. Anlıyorum — çalışan kodu değiştirmek risk taşır.

Ama şunu sormak gerekiyor: Mevcut kodun bakım maliyeti nedir?

Her yeni özellik ne kadar sürüyor? Yeni geliştirici uyumu kaç hafta alıyor? Test coverage'ı gerçekten yeterli mi? Bir gereksinim değişikliği kaç dosyayı etkiliyor?

Bu sorulara verilen cevaplar genellikle modelin olmadığı elle yazılmış durum makinesi kodunun gerçek maliyetini ortaya koyar.


Sonuç

Elle durum makinesi kodu yazmak yanlış değildir — ama ölçeklenmez. Sistem büyüdükçe, gereksinimler değiştikçe, ekip genişledikçe model ile implementasyon arasındaki uçurum kapanmaz, büyür.

Model tabanlı yaklaşımın değeri şuradan gelir: tasarım niyeti kaynak kodda yaşar, test edilebilirlik yapısal olarak sağlanır, yeni geliştirici .umt dosyasını okuyarak sistemi anlar.

UMTSM bu yaklaşımı gömülü C/C++ projelerine taşımak için geliştirilmiştir. Bir sonraki yazıda üretilen kodun nasıl test edildiğini, otomatik üretilen test fixture'larının nasıl kullanıldığını inceliyoruz.


UMTSM ile ilgili sorularınız veya projeleriniz için iletişime geçin.