Durum makinesi bir yazılımda yazılım modüllerinin durum ve akış kontrolünü modellemek ve yönetmek için kullanılır. İlk bölümde durum makinelerinin genel kavramlarını gerçek bir cihaz, otomat makinesi üzerinden ele almıştık.
Otomat makinesinin çalışma şekli ve yapısı aşağıdaki gibi olsun.
- Makinede dört adet yiyecek bölümü ve bunlara ait dört adet seçim tuşu bulunacaktır.
- Yiyeceklerin her biri aynı maddi değere sahiptir ve her bir yiyeceğin bedeli 1 TL’dir. Makineye sadece 1 TL atılabilmektedir, diğer madeni paralar atılamamaktadır.
- Kullanıcı önce parayı makineye atar ve ardından ürün seçimini yapar. Makine seçilen yiyeceği verir.
- Kullanıcı “iptal” tuşuna basar ise para iadesi yapılır.
Şimdi otomat makinesi yazılımının durum makinesi tasarımını gerçekleştirelim. Durum makinesi için, cihaz durumlarını, olayları ve durumlar arası geçişleri analiz etmemiz gerekir. Bir önceki yazıda temel kavramları irdelerken zaten otomat makinesinin yapısını irdelemiştik.
- Durumlar
Durum | Açıklama |
ParaGirisiBekle | Bu durum sadece para atılma durumuyla ilgilenmektedir. Bu durumda ürün seçimi ve iptali yapılamaz. |
ÜrünSeciminiBekle | Ürün seçimini bekler. Kullanıcı iptal tuşuna basar ise para iadesi yapar. Ürün seçimi yapılırsa ürün verir, bu andan itibaren iptal yapılamaz. Ürün verme işlemi tamamlandığından döngü tamamlanmıştır. |
- Olaylar
Olay | Açıklama |
onParaAtıldı | Otomata para atıldığında gerçekleşir. Bu olay bir durum geçişine sebep olur. Kullanıcı kaynaklıdır. |
onUrunSecildi | Urun seçim tuşlarından birine basıldığında gerçekleşir. Bu olay bir durum geçişine sebep olur. Kullanıcı kaynaklıdır. |
onUrunVerildi | Ürün verme işlemi tamladığında gerçekleşir. Sistem tarafından üretilir. Durum geçişine sebep olur. |
onİptal | Para iadesi yap |
- Geçişler
Olay | Geçiş/Aksiyon |
Başlangıç | ParaGirisiBekle |
onParaAtıldı | ParaGirisiBekle àÜrünSeciminiBekle |
onUrunVerildi | ÜrünSeciminiBekle à ParaGirisiBekle |
Aslında yukarıdaki tabloları yapmamıza gerek yok. Elimize kalem kâğıt alıp UML diyagramını çizmeye başladığımızda durumlar, olaylar ve bunların arasındaki ilişki ortaya çıkıyor. Aşağıda örneğimize ait UML diyagramı görülmektedir.
Bu noktadan sonra kodlamaya geçebiliriz.
Durum makinemizin durumları ve olaylarını birer enum olarak tanımlarız.
Programımız aşağıdaki çıktıyı üretmektedir.
Tasarıma direk kodlama üzerinden başlamak basit uygulamalar için sorun oluşturmasa da büyük sistemler için akış diyagramları ve UML diyagramları kaçınılmazdır. Bir durum makinesi tasarımı yapılırken UML diyagramlarından yararlanmak sistemi kâğıt üzerinde görmeye ve durumlar-olaylar arasındaki ilişkiyi belirlemede oldukça kolaylık sağlamaktadır. Ayrıca hem yazılan kodun yorumlanmasında ve dokümantasyonunda hem daha sonra sistem ve kodlama üzerinde yapılacak değişiklikler için oldukça faydalı olacaktır. UML diyagramından kodlamaya geçmekte oldukça kolaylık saplamaktadır.
Bu yazıda bir durum makinesini en basit haliyle ele aldık. Örneğimizde olmasa da büyük durum makinelerinde iç-içe(nested) durumlar oluşmakta ve bu kod yazımını ve bakımını oldukça zorlaştırmaktadır. Ayrıca literatürde “spagetti-kod” olarak bilinen durumun oluşmasına imkan sağlamaktadır. Yukarıdaki yaklaşımın dışında tablo güdümlü(table driven), fonksiyon pointer tabanlı gibi farklı yaklaşımların olduğunu belirtmek isterim. Bu yaklaşımlar ile spagetti-kod oluşumunun önüne geçmek mümkün olabilir. Ayrıca “hiyerarşik durum makineleri” ise yazıda ele aldığımız “sonlu durum makinelerinin” eksik yönlerini kapatmakta ve kod tekrarını ve fsm’nin yetersiz kaldığı yerlere çözümler sunmaktadır.
Faydalı olması dileğiyle.