Przychodzi do nas klient:
Potrzebujemy utworzyć małą aplikację, która na podstawie wybranego zawodu wyliczy nam miesięczne wynagrodzenie. Do tego wynagrodzenie zależy od ilości przepracowanych godzin oraz stawki. Jeśli kierownicy przepracują więcej niż 160, to ich stawka od tej chwili rośnie 2x.
Pierwsze co musimy zrobić, to otworzyć sobie kod źródłowy z naszego poprzedniego przykładu.
Weźmy się może za dodanie nowej funkcjonalności dla kierownika, czyli jeśli jego ilość godzin będzie większa od 160, to jego stawka sie podwaja:
public float ObliczWynagrodzenie(UInt16 iloscPrzepracowanychGodzin)
{
if (iloscPrzepracowanychGodzin > 160)
{
return (STAWKA_GODZINOWA * 160) + (iloscPrzepracowanychGodzin - 160 * STAWKA_GODZINOWA);
}
return STAWKA_GODZINOWA * iloscPrzepracowanychGodzin;
}
Dość szybko nam poszło, lecz hola amigo!
Nagle przychodzi klient:
Witam, rozmyśliliśmy się co do podstawowego wymiaru pracy kierownika, nie chcemy by wynosił 160, lecz 170.
Extra, teraz musimy dokonać zmian w 3 miejscach, a na dodatek jeśli zrobi to obca osoba, to może nawet się nie zorientować co oznacza cyfra 160. Nie możemy tak tego zostawić. Musimy poddać kod drobnej refaktoryzacji. Tworzymy stałą PODSTAWOWY_WYMIAR_PRACY i przypisujemy jej wartość 160, następnie wszędzie w klasie 160 zamieniamy na tą stała. Proszę!
class Kierownik : IPracownik
{
private const UInt16 STAWKA_GODZINOWA = 50;
private const UInt16 PODSTAWOWY_CZAS_PRACY = 160;
public float ObliczWynagrodzenie(UInt16 iloscPrzepracowanychGodzin)
{
if (iloscPrzepracowanychGodzin > PODSTAWOWY_CZAS_PRACY)
{
return (STAWKA_GODZINOWA * PODSTAWOWY_CZAS_PRACY) + (iloscPrzepracowanychGodzin - PODSTAWOWY_CZAS_PRACY * STAWKA_GODZINOWA);
}
return STAWKA_GODZINOWA * iloscPrzepracowanychGodzin;
}
}
Teraz kod jest czytelniejszy i bardziej elastyczny. Jak przyjdzie klient i powie, że jednak podstawowy czas pracy dla kierownika ma wynosić 180, to nikt nie będzie miał problemów z tą zmianą. Lecz metoda ObliczWynagrodzenie wydaje sie bardzo skomplikowana/rozciągnięta, musimy ją jakoś uprościć.
warunek:
if (iloscPrzepracowanychGodzin > PODSTAWOWY_CZAS_PRACY)
zamienimy na statyczna metodę:
private static bool CzyPodstawowyCzasPracyZostalPrzekroczony(UInt16 iloscPrzepracowanychGodzin)
{
return iloscPrzepracowanychGodzin > PODSTAWOWY_CZAS_PRACY;
}
dzięki temu po przeczytaniu warunku od razu się zorientujemy co ulega sprawdzeniu.
ta linijka jest jeszcze trochę zagmatwana:
return (STAWKA_GODZINOWA * PODSTAWOWY_CZAS_PRACY) + (iloscPrzepracowanychGodzin - PODSTAWOWY_CZAS_PRACY * STAWKA_GODZINOWA);
stwórzmy z niej 2 metody:
wyrażenie:
(STAWKA_GODZINOWA * PODSTAWOWY_CZAS_PRACY)
zamienimy na:
private static int ObliczPodstawoweWynagrodzenie()
{
return STAWKA_GODZINOWA * PODSTAWOWY_CZAS_PRACY;
}
natomiast:
(iloscPrzepracowanychGodzin - PODSTAWOWY_CZAS_PRACY * STAWKA_GODZINOWA)
na:
private static int ObliczGodzinyNadliczbowe(UInt16 iloscPrzepracowanychGodzin)
{
return iloscPrzepracowanychGodzin - PODSTAWOWY_CZAS_PRACY * STAWKA_GODZINOWA;
}
Proszę, z linijki niemal tak długiej jak "spaghetti" udało nam się utworzyć całkiem zgrabny kod:
public float ObliczWynagrodzenie(UInt16 iloscPrzepracowanychGodzin)
{
if (CzyPodstawowyCzasPracyZostalPrzekroczony(iloscPrzepracowanychGodzin))
{
return ObliczPodstawoweWynagrodzenie() +
ObliczGodzinyNadliczbowe(iloscPrzepracowanychGodzin);
}
return STAWKA_GODZINOWA * iloscPrzepracowanychGodzin;
}
Jak widać refaktoryzacja działa cuda.
Uff uporaliśmy sie z wymogiem naszego klienta, jesteśmy bardzo z siebie zadowoleni i już wiemy, że nic nam dobrego humoru nie popsuje.
Nagle dzwoni klient:
Witam! Zapomniałem powiedzieć, ze piekarze muszą mieć inaczej liczoną stawkę w nocy.
Hmm co by tu wykombinować? Żeby to zrobić to dla piekarzy gdzieś trzeba byłoby utworzyć zmienne, które by reprezentowały ilość przepracowanych godzin w dzień oraz w nocy. Jeśli tak zrobimy, musielibyśmy naruszyć nasza metodę ObliczWynagrodzenie przyjmującą wyłączenie 1 zmienną a nie 2! Jeśli to zrobimy będziemy musieli dokonać zmian we wszystkich klasach implementujących IPracownik. Nie możemy na to sobie pozwolić!
Telefon od klienta:
Witam, jeszcze o jednej zmianie zapomniałem wam powiedzieć, jeśli piekarz wyrobi w święta jakieś godziny to musimy mu je pomnożyć przez 2.
istny horror... cdn.
a tym czasem tutaj znajdują się źródła
Brak komentarzy:
Prześlij komentarz