Niedawno podczas recenzji kodu natknąłem się na kod napisany przez nowego kolegę, który zawiera wzór z zapachem. Podejrzewam, że decyzje mojego kolegi opierają się na zasadach zaproponowanych w słynnej książce Clean Code (i być może także w innych podobnych książkach).
Rozumiem, że konstruktor klasy jest całkowicie odpowiedzialny za utworzenie ważnego obiektu i że jego głównym zadaniem jest przypisanie właściwości obiektu (prywatnego). Oczywiście może się zdarzyć, że opcjonalne wartości właściwości mogą być ustawione metodami innymi niż konstruktor klasy, ale takie sytuacje są raczej rzadkie (choć niekoniecznie złe, pod warunkiem, że reszta klasy bierze pod uwagę opcjonalność takiej właściwości). Jest to ważne, ponieważ pozwala upewnić się, że obiekt jest zawsze w poprawnym stanie.
Jednak w kodzie, który napotkałem, większość wartości właściwości jest faktycznie ustawiana innymi metodami niż konstruktor. Wartości wynikające z obliczeń są przypisywane właściwościom, które mają być używane w kilku prywatnych metodach w całej klasie. Autor najwyraźniej używa właściwości klasy tak, jakby były zmiennymi globalnymi, które powinny być dostępne w całej klasie, zamiast parametryzować te wartości do funkcji, które ich potrzebują. Dodatkowo metody klasy powinny być wywoływane w określonej kolejności, ponieważ inaczej klasa niewiele by zrobiła.
Podejrzewam, że ten kod został zainspirowany radą, aby metody były krótkie (<= 5 wierszy kodu), aby uniknąć dużych list parametrów (<3 parametrów) i że konstruktory nie mogą działać (np. Wykonywać jakieś obliczenia jest to niezbędne dla ważności obiektu).
Teraz oczywiście mogę uzasadnić ten wzorzec, jeśli mogę udowodnić, że wszelkiego rodzaju nieokreślone błędy potencjalnie powstają, gdy metody nie są wywoływane w określonej kolejności. Przewiduję jednak, że odpowiedzią na to będzie dodanie walidacji, które sprawdzą, czy właściwości muszą zostać ustawione po wywołaniu metod, które wymagają ustawienia tych właściwości.
Wolałbym jednak całkowicie zmienić kod, aby klasa stała się niebieskim drukiem na rzeczywistym obiekcie, a nie serią metod, które należy wywoływać (proceduralnie) w określonej kolejności.
Czuję, że kod, który napotkałem, pachnie. W rzeczywistości uważam, że istnieje dość wyraźne rozróżnienie, kiedy zapisać wartość we właściwości klasy, a kiedy umieścić ją w parametrze dla innej metody do użycia - nie sądzę, że mogą one być alternatywami dla siebie . Szukam słów na to rozróżnienie.