Moje przemyślenia na temat klas statycznych zapisałem we wcześniejszym wątku :
Uwielbiałem klasy użytkowe wypełnione metodami statycznymi. Dokonali wielkiej konsolidacji metod pomocniczych, które w innym przypadku leżałyby wokół powodując piekło nadmiarowości i utrzymania. Są bardzo łatwe w użyciu, bez tworzenia instancji, bez usuwania, po prostu odpal i zapomnij. Wydaje mi się, że była to moja pierwsza nieświadoma próba stworzenia architektury zorientowanej na usługi - wiele bezpaństwowych usług, które wykonały swoją pracę i nic więcej. Jednak wraz z rozwojem systemu nadchodzą smoki.
Wielopostaciowość
Powiedzmy, że mamy metodę UtilityClass.SomeMethod, która szczęśliwie się rozwija. Nagle musimy nieco zmienić funkcjonalność. Większość funkcji jest taka sama, ale musimy jednak zmienić kilka części. Gdyby nie była to metoda statyczna, moglibyśmy stworzyć klasę pochodną i w razie potrzeby zmienić zawartość metody. Ponieważ jest to metoda statyczna, nie możemy. Jasne, jeśli musimy tylko dodać funkcjonalność przed lub po starej metodzie, możemy utworzyć nową klasę i wywołać w niej starą klasę - ale to po prostu obrzydliwe.
Interfejs nieszczęścia
Z powodów logicznych nie można definiować metod statycznych za pomocą interfejsów. A ponieważ nie możemy przesłonić metod statycznych, klasy statyczne są bezużyteczne, gdy musimy przekazać je za pomocą interfejsu. To uniemożliwia nam użycie klas statycznych jako części wzorca strategii. Możemy rozwiązać niektóre problemy, przekazując delegatów zamiast interfejsów.
Testowanie
Zasadniczo idzie to w parze z problemami interfejsu wspomnianymi powyżej. Ponieważ nasza zdolność do wymiany implementacji jest bardzo ograniczona, będziemy mieli problemy z zastąpieniem kodu produkcyjnego kodem testowym. Ponownie możemy je zawinąć, ale będzie to wymagało od nas zmiany dużych części naszego kodu, abyśmy mogli akceptować opakowania zamiast rzeczywistych obiektów.
Przyspiesza plamy
Ponieważ metody statyczne są zwykle używane jako metody narzędziowe, a metody narzędziowe zwykle mają różne cele, szybko otrzymamy dużą klasę wypełnioną niespójną funkcjonalnością - idealnie, każda klasa powinna mieć jeden cel w systemie. Wolę pięć razy więcej zajęć, o ile ich cele są dobrze określone.
Pełzanie parametrów
Na początek ta słodka i niewinna metoda statyczna może wymagać jednego parametru. W miarę wzrostu funkcjonalności dodaje się kilka nowych parametrów. Wkrótce dodawane są dodatkowe parametry, które są opcjonalne, dlatego tworzymy przeciążenia metody (lub po prostu dodajemy wartości domyślne w językach, które je obsługują). Wkrótce mamy metodę, która przyjmuje 10 parametrów. Tylko pierwsze trzy są naprawdę wymagane, parametry 4-7 są opcjonalne. Ale jeśli parametr 6 jest określony, należy również wypełnić 7-9 ... Gdybyśmy stworzyli klasę, której jedynym celem jest zrobienie tego, co zrobiła ta metoda statyczna, moglibyśmy rozwiązać ten problem, przyjmując wymagane parametry w konstruktor i umożliwiając użytkownikowi ustawianie wartości opcjonalnych za pomocą właściwości lub metod ustawiania wielu współzależnych wartości w tym samym czasie. Również,
Wymaganie od konsumentów utworzenia instancji klas bez powodu
Jednym z najczęstszych argumentów jest: dlaczego żądać od konsumentów z naszej klasy utworzenia instancji w celu wywołania tej pojedynczej metody, nie mając przy tym później żadnej instancji? Utworzenie instancji klasy jest bardzo tanią operacją w większości języków, więc szybkość nie stanowi problemu. Dodanie do wiersza dodatkowego wiersza kodu jest niskim kosztem, jeśli chodzi o położenie podwalin pod znacznie łatwiejsze w utrzymaniu rozwiązanie w przyszłości. I wreszcie, jeśli chcesz uniknąć tworzenia instancji, po prostu stwórz opakowanie singletonowe swojej klasy, które pozwala na łatwe ponowne użycie - chociaż powoduje to, że twoja klasa jest bezstanowa. Jeśli nie jest to bezstanowy, nadal możesz tworzyć statyczne metody otoki, które obsługują wszystko, a jednocześnie dają Ci wszystkie korzyści na dłuższą metę. Wreszcie,
Tylko Sith zajmuje się absolutami
Oczywiście są wyjątki od mojej niechęci do metod statycznych. Prawdziwe klasy użyteczności, które nie stanowią żadnego ryzyka wzdęcia, stanowią doskonałe przypadki dla metod statycznych - na przykład System.Convert. Jeśli Twój projekt jest jednorazowy i nie wymaga żadnych przyszłych prac konserwacyjnych, ogólna architektura naprawdę nie jest bardzo ważna - statyczna lub niestatyczna, nie ma większego znaczenia - jednak szybkość programowania ma znaczenie.
Standardy, standardy, standardy!
Korzystanie z metod instancji nie przeszkadza również w stosowaniu metod statycznych i odwrotnie. Tak długo, jak istnieje uzasadnienie różnicowania i jest ono znormalizowane. Nie ma nic gorszego niż przeglądanie warstwy biznesowej rozłożonej na różne metody wdrażania.