In Martin Fowler UML Damıtılmış , o (hayır cinas tasarlamak) Bölüm 10 Durum Makinesi Diyagramları (vurgu benim) buyurmuştur:
Bir durum diyagramı üç ana yolla uygulanabilir: iç içe geçmiş anahtar , Durum modeli ve
durum tabloları .
Bir cep telefonunun ekranının durumlarının basitleştirilmiş bir örneğini kullanalım:
İç içe anahtar
Fowler bir C # kodu örneği verdi, ancak bunu örneğime uyarladım.
public void HandleEvent(PhoneEvent anEvent) {
switch (CurrentState) {
case PhoneState.ScreenOff:
switch (anEvent) {
case PhoneEvent.PressButton:
if (powerLow) { // guard condition
DisplayLowPowerMessage(); // action
// CurrentState = PhoneState.ScreenOff;
} else {
CurrentState = PhoneState.ScreenOn;
}
break;
case PhoneEvent.PlugPower:
CurrentState = PhoneState.ScreenCharging;
break;
}
break;
case PhoneState.ScreenOn:
switch (anEvent) {
case PhoneEvent.PressButton:
CurrentState = PhoneState.ScreenOff;
break;
case PhoneEvent.PlugPower:
CurrentState = PhoneState.ScreenCharging;
break;
}
break;
case PhoneState.ScreenCharging:
switch (anEvent) {
case PhoneEvent.UnplugPower:
CurrentState = PhoneState.ScreenOff;
break;
}
break;
}
}
Durum modeli
GoF State kalıbı ile örneğimin bir uygulaması:
Durum Tabloları
Fowler'dan ilham alarak, işte örneğim için bir tablo:
Kaynak Durum Hedef Durum Olay Koruma Eylemi
-------------------------------------------------- ------------------------------------
Ekran Kapalı Ekran Kapalı düğmesine basın Buton gücü Düşük ekran Düşük Güç Mesaj
ScreenOff ScreenOn pressButton! PowerLow
ScreenOn ScreenOff basınButton
ScreenOff ScreenCharging fişi Güç
Ekran Üzerinde Ekran Şarj fişi Güç
ScreenCharging ScreenOff unplugPower
karşılaştırma
İç içe geçmiş anahtar, tüm mantığı tek bir noktada tutar, ancak çok sayıda durum ve geçiş olduğunda kodun okunması zor olabilir. Muhtemelen diğer yaklaşımlardan daha güvenli ve daha kolaydır (polimorfizm veya yorumlama yok).
Durum modeli uygulaması, mantığı potansiyel olarak birkaç ayrı sınıfa yayar ve bu da onu bir bütün olarak anlamayı bir sorun haline getirebilir. Öte yandan, küçük sınıfları ayrı ayrı anlamak kolaydır. Geçişler ekleyerek veya kaldırarak davranışı değiştirirseniz tasarım özellikle kırılgandır, çünkü bunlar hiyerarşideki yöntemlerdir ve kodda birçok değişiklik olabilir. Küçük arayüzlerin tasarım prensibine göre yaşıyorsanız, bu modelin pek de iyi olmadığını göreceksiniz. Ancak, durum makinesi kararlıysa, bu tür değişikliklere gerek olmayacaktır.
Durum tabloları yaklaşımı, içerik için bir tür yorumlayıcı yazmayı gerektirir (kullandığınız dilde düşünceleriniz varsa bu daha kolay olabilir) ve bu, önceden yapılması gereken çok iş olabilir. Fowler'ın işaret ettiği gibi, tablonuz kodunuzdan ayrı ise, yazılımınızın davranışını yeniden derlemeden değiştirebilirsiniz. Bununla birlikte, bunun bazı güvenlik etkileri vardır; yazılım, harici bir dosyanın içeriğine göre davranıyor.
Düzenleme (gerçekten C dili için değil)
Muhtemelen birinci sınıf işlevlere sahip diller tarafından kolaylaştırılan akıcı bir arayüz (diğer adıyla dahili Etki Alanına Özel Dil) yaklaşımı da vardır . Vatansız kütüphanesi var ve bu blog gösterileri kodu ile basit bir örnek. Bir Java uygulaması (Java8 öncesi) tartışılmaktadır. GitHub'da da bir Python örneği gösterildim .