Jeśli funkcja jest „czysta”, nie widzę problemów. Funkcja czysta działa tylko w parametrach wejściowych i na tej podstawie zapewnia wynik. Nie zależy od żadnego globalnego stanu ani kontekstu zewnętrznego.
Jeśli spojrzę na twój własny przykład kodu:
public class Class1
{
public static string GetSomeString()
{
// do something
}
}
Ta funkcja nie przyjmuje żadnych parametrów. Zatem prawdopodobnie nie jest czysty (jedyną czystą implementacją tej funkcji byłoby zwrócenie stałej). Zakładam, że ten przykład nie jest reprezentatywny dla twojego rzeczywistego problemu, ja tylko wskazuję, że prawdopodobnie nie jest to czysta funkcja.
Weźmy inny przykład:
public static bool IsOdd(int number) { return (number % 2) == 1; }
Nie ma nic złego w tym, że ta funkcja jest statyczna. Możemy nawet przekształcić to w funkcję rozszerzenia, dzięki czemu kod klienta będzie jeszcze bardziej czytelny. Funkcje rozszerzeń są w zasadzie tylko szczególnym rodzajem funkcji statycznych.
Telastyn poprawnie wspomina o współbieżności jako potencjalnym problemie z elementami statycznymi. Ponieważ jednak ta funkcja nie korzysta ze stanu współdzielonego, nie występują tutaj problemy z współbieżnością. Tysiąc wątków może wywoływać tę funkcję jednocześnie bez żadnych problemów z współbieżnością.
W środowisku .NET metody rozszerzenia istnieją już od dłuższego czasu. LINQ zawiera wiele funkcji rozszerzających (np. Enumerable.Where () , Enumerable.First () , Enumerable.Single () itp.). Nie uważamy ich za złe, prawda?
Testowanie jednostkowe może często przynieść korzyści, gdy kod wykorzystuje wymienne abstrakcje, umożliwiając testowi jednostkowemu zastąpienie kodu systemowego podwójnym testem. Funkcje statyczne zabraniają tej elastyczności, ale jest to szczególnie ważne na granicach warstwy architektonicznej, gdzie chcemy na przykład zastąpić rzeczywistą warstwę dostępu do danych fałszywą warstwą dostępu do danych.
Jednak pisząc test dla obiektu, który zachowuje się inaczej, w zależności od tego, czy jakaś liczba jest nieparzysta, czy parzysta, tak naprawdę nie musimy być w stanie zastąpić IsOdd()
funkcji alternatywną implementacją. Podobnie nie widzę, kiedy musimy zapewnić inną Enumerable.Where()
implementację do celów testowania.
Sprawdźmy więc czytelność kodu klienta dla tej funkcji:
Opcja a (z funkcją zadeklarowaną jako metoda rozszerzenia):
public void Execute(int number) {
if (number.IsOdd())
// Do something
}
Opcja b:
public void Execute(int number) {
var helper = new NumberHelper();
if (helper.IsOdd(number))
// Do something
}
Funkcja statyczna (rozszerzenie) sprawia, że pierwszy fragment kodu jest znacznie bardziej czytelny, a czytelność ma duże znaczenie, więc w razie potrzeby używaj funkcji statycznych.