poniedziałek, 5 grudnia 2011

Windows Forms i pokusa dwukliku

    Biblioteka Windows Forms została napisana w taki sposób, że komponenty przekazują informacje o zmianie swojego stanu przy użyciu zdarzeń (ang. events). Fachowo taką architekturę określa się wzorcem projektowym Obserwator. Jest to bardzo fajny wzorzec, bo pozwala na rozdzielenie warstwy prezentacji od logiki biznesowej. Logika biznesowa podpinana jest pod zdarzenia okienek i voilà! - mamy gotową aplikację w architekturze warstwowej.
    Żeby powyższe optymistyczne założenie stało się prawdziwe musi być spełniony jeden warunek: programista musi zaimplementować logikę biznesową POZA kodem kontrolki. Niestety, Visual Studio bardzo mocno kusi programistę, żeby wrzucił wszystko do kodu kontrolki: gdy dwukliknie się dowolną kontrolkę w designerze VS, środowisko samo wygeneruje nam kod do obsługi zdarzenia WEWNĄTRZ kodu kontrolki. Na dodatek ustawi kursor w ciele nowo wygenerowanej metody. Podświadomy przekaz od Microsoftu jaki dociera do wielu programistów jest następujący: „that's the way it should be done” :-(
    Chciałbym jeszcze zwrócić uwagę, że wzorzec projektowy Obserwator zupełnie traci swój sens i swoje zalety, gdy obiekt obserwowany jest równocześnie obserwatorem (polecam przeczytać zalety Obserwatora wymienione na Wikipedii).
    Żeby nie było, że jestem jakimś krytykującym Microsoft szpiegiem z krainy Javy, dodam jeszcze że zupełnie analogiczna sytuacja ma miejsce w javowym Swingu używanym w NetBeansie. Po dwukliknięciu np. JButtona generowana jest metoda obsługująca zdarzenie w kodzie klasy, która powinna być odpowiedzialna wyłącznie za renderowanie kontrolek.
    W kolejnym wpisie na tym blogu postaram się zaproponować taką architekturę aplikacji opartych na Windows Forms, która rozdzieli prezentację od logiki oraz umożliwi testowanie jednostkowe (no tak, zapomniałem dodać, że w przypadku wszystko robiących kontrolek możemy zapomnieć o testach jednostkowych, ale to chyba oczywiste?).



PS Wg mnie Visual Studio powinno generować takie metody po dwukliknięciu kontrolki w designerze:
private void button1_Click(object sender, EventArgs e)
{
// TODO: if your programming skills let you write
// multi-class solutions:
// remove this method & put your logic elsewhere
// otherwise:
// code here on your own responsibility
}

1 komentarz:

  1. Niestety nierzadko przychodzi nam pracować z kontrolkami odziedziczonymi po poprzednich pokoleniach programistów. Kontrolki te są niekiedy bardzo mądre (niemalże mądrzejsze od nas). Wszystko potrafią, wszystko robią same. Same decydują co i jak mają wyświetlać. Świetnie tańczą, ślicznie śpiewają, uśmiechają się wdzięcznie, a jak je ładnie poprosić, to i obiad dla nas ugotują. Słowem - sielanka. Problemy zaczynają się dopiero, gdy trzeba w naszej super kontrolce dokonać jakiejś zmiany...

    ..i wtedy przychodzi nam pokutować za nie nasze grzechy. No bo jak tu zapanować nad takim kodem? Jak znaleźć błąd? Jak rozszerzyć funkcjonalność? A wszystko dlatego, że ktoś, gdzieś, kiedyś uległ POKUSIE DWUKLIKU. Ćwiczmy silną wolę, zwalczmy pokusę!

    PS Genialny kapelusz. Też chcę taki!

    OdpowiedzUsuń