Ślub. Factory żeni się z IOC

Małżeństwo

Małżeństwo to nie taka prosta sprawa. Są różne i różnie się układają, różni ludzie się do tego mieszają czasem wychodzi to lepiej a czasem gorzej. Podobnie jest w programowaniu. Ostatnio musiałem ożenić IOC z Factory. Problem który się pojawił to tworzenie obiektu na podstawie jakiegoś tam parametru wejściowego, na początku miałem tylko jeden przypadek (np. RssChannel) i musiałem tylko ten przypadek obsługiwać, mogłem spokojnie wstrzyknąć handler i było cacy. Potem (w zasadzie teraz) mam drugi przypadek (Person) i na początku także wstrzykiwałem sobie handler dla tego przypadku. W ramach porządkowania robiłem małe poprawki w kodzie i nie mogłem przejść obok tego bez reakcji. Poza tym OCP patrzyło na mnie spode łba tak paskudnie. Continue reading

Feature request jak to ugryźć

Mało czasu

Czas goni, a rąk i głów i czasu do implementacji ficzerów brakuje. Co wtedy robić, od którego zacząć robić żeby było lepiej dla aplikacji i dla ludzi, a na końcu dla mnie i mojego portfela?

Zamiast zastanawiać się w ten sposób, może warto oddać głos użytkownikom? Niech oni klikają w system, system zbiera te informacje i w krótkim czasie można się dowiedzieć co było klikane najczęściej i właśnie na tym skupić kolejna działania rozwojowe.

Mój pomysł

Jak ja do tego podszedłem? W poprzednim wpisie pokazałem jak wygląda u mnie pasek pod każdym w rss (http://jaroslawstadnicki.pl/2016/04/font-awesome-w-mvc/).
Kod odpowiedzialny za wyświetlenie tego paska wygląda w taki sposób: Continue reading

Konwencje w autofacu

Część z nas jest mniej lub bardziej leniwa. Części może przeszkadzać taki zapis, a części nie.

Szczególnie część, gdzie powtarzają się różnego rodzaju serwisy i repozytoria (@7-@14) oraz (@21-@27). Co czynić, jak zrobić to samo za mniej? Konwencje i autoskanowanie assembly’ów. Jak? Poniżej prosta ściągawka: Continue reading

Zamień bóla na enuma

Dlaczego zamienić? Moim zdaniem czytelniej i jasno sformułowana myśl i łatwiej zrozumieć. Nie chodzi o prosty przypadek, gdzie zamiana polegałaby na zamianie true/false na MyEnum.True/MyEnum.False – nie nie, to byłoby szaleństwem. Ale może od razu do kodu, bo czas nagli dzisiaj.

Pierwszy przypadek, wszystko działa jak należy:

Jakaś tam klasa filtrów, przyjmuje (@3) identyfikator, nazwę i bit, które oznacza że filtr będzie grupą lub nie (w zasadzie nie wiadomo, czym jest nie-grupa)

Teraz wykorzystanie:

Zasadniczo prosty kod, jest jakaś lista filtrów (@5). Następnie dodajemy filtry; pierwsze id, jakaś nazwa i true, potem id, nazwa i false. Osoba nowa w projekcie, lub nowa w tej części kodu na pierwszy rzut oka nie będzie wiedzieć co to oznacza. Następne dwie linijki są trochę bardziej rozgadane, bo jawnie mówią jak interpretować ostatniego bool’a.
Dalej szukamy tylko tych, gdzie IsGroup jest ustawione na true (@12). Jeszcze dalej wołamy metodę, która robi to samo, ale na podstawie parametru wejściowego (@18). Najczęściej gdy się tworzy takie metody nie zwraca się dużej uwagi na nazwę parametru, bo albo to R# wygenerował, a on robi dobrze, albo jest to jedna linijka i nie muszę się nad tym za bardzo skupiać. Rzeczywiście sama metoda jest prosta, trudno się pomylić do czego służy parametr i gdzie go wykorzystać.
Spójrzcie teraz na klienta tej metody, ma przesłać dwa parametry, listę filtrów (to proste), a potem flagę która oznacza group – group co?! Trzeba zajrzeć do ciała metody, żeby sprawdzić co oznacza ten parametr i jak mam go wykorzystać. Można też poprawić nazwę parametru lub (czuję obrzyd jak to piszę) napisać dokumentacja.

A co gdyby napisać kod w taki sposób:

Na scenę wchodzi tajemniczy FilterType:

Jak widać, tajemniczy bohater to enum, które jawnie definiuje jakiego rodzaju może być filtr:

  • 0 – nie został określony, nikt nie wie, nikt nie słyszał. Jeśli w ten sposób został zainicjalizowany, to najprawdopodobniej nie zostanie nigdy wykorzystany
  • 1- Typ grupowy
  • 2- Typ pojedynczy (aha, teraz to trochę jaśniejsze)

Prosty klient klasy Filtr, może wyglądać jakoś tak:

Na początku ponownie tworzymy listę, tym razem nie trzeba zgadywać co oznacza true/false. Nie trzeba także uciekać się do używania nazwanych parametrów aby rozjaśnić intencje.
Następnie gdy wybieramy z kolekcji filtry (@12), znowu w jasny sposób mówimy o typie, który nas interesuje. I wreszcie na koniec metoda filtrująca (@18) także w jawny sposób definiuje parametry których wymaga do działania.

Co jeszcze dobrego płynie z przyjęcia enuma? Jeśli pojawi się nowy rodzaj, nie trzeba będzie wprowadzać kolejnego bool’a który będzie mówić, czy filtr jest czy nie jest danego rodzaju. Domyślnie filtr jest nie znanego typu, więc wszystkie podczas poszukiwać za grupowym/pojedynczym takie znaleziska się nie pojawią. Nawet gdy nazwa parametru będzie do bani, sam tym parametru sprzeda intencje programisty i użytkownik metody (@18) będzie wiedzieć jakiego rodzaju wartość ma przesłać, aby otrzymać interesująco go wynik.

I jeszcze na koniec: oczywiście że ciężko tworzyć enum’y do każdego wykorzystania bool’a. Równie ciężko jest pisać kod który działa i jest czytelny, bezbłędny czy zoptymalizowany – a jednak każdy się stara.

Miłego wieczoru!