Wszyscy wiemy, że magiczne liczby (wartości zakodowane na stałe) mogą siać spustoszenie w twoim programie, szczególnie gdy nadszedł czas na modyfikację części kodu, która nie ma komentarzy, ale gdzie wytyczasz linię?
Na przykład, jeśli masz funkcję, która oblicza liczbę sekund między dwoma dniami, czy zastępujesz
seconds = num_days * 24 * 60 * 60
z
seconds = num_days * HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE
W którym momencie zdecydujesz, że jest całkowicie oczywiste, co oznacza wartość zakodowana na stałe, i zostaw to w spokoju?
refactoring
coding-standards
maintainability
oosterwal
źródło
źródło
seconds = CALC_SECONDS(num_days);
TimeSpan.FromDays(numDays).Seconds;
HOURS_PER_DAY will never need to be altered
) nigdy nie będziesz kodować oprogramowania wdrażanego na Marsie. : POdpowiedzi:
Istnieją dwa powody, aby używać stałych symbolicznych zamiast literałów numerycznych:
Aby uprościć konserwację, jeśli zmienią się magiczne liczby. Nie dotyczy to twojego przykładu. Jest bardzo mało prawdopodobne, aby zmieniła się liczba sekund w ciągu godziny lub liczba godzin w ciągu dnia.
Aby poprawić czytelność. Wyrażenie „24 * 60 * 60” jest dość oczywiste dla prawie wszystkich. „SECONDS_PER_DAY” też, ale jeśli polujesz na błąd, być może będziesz musiał sprawdzić, czy SECONDS_PER_DAY został poprawnie zdefiniowany. W skrócie jest wartość.
W przypadku liczb magicznych, które pojawiają się dokładnie raz i są niezależne od reszty programu, decyzja o utworzeniu symbolu dla tej liczby jest kwestią gustu. W razie wątpliwości idź dalej i stwórz symbol.
Nie rób tego:
źródło
publid final int FOUR = 3;
public static int THREE = 3;
... uwaga - niefinal
!Przestrzegałbym zasady, by nigdy nie mieć magicznych liczb.
Podczas
Jest doskonale czytelny przez większość czasu, po kodowaniu przez 10 godzin dziennie przez trzy lub cztery tygodnie w trybie crunch
jest znacznie łatwiejszy do odczytania.
Sugestia FrustratedWithFormsDesigner jest lepsza:
a nawet lepiej
Rzeczy przestają być oczywiste, kiedy jesteś bardzo zmęczony. Kod defensywnie .
źródło
Czas powiedzieć „nie” prawie zawsze. Czasy, w których uważam, że łatwiej jest używać liczb zakodowanych na stałe, są w miejscach takich jak układ interfejsu użytkownika - tworzenie stałej dla pozycjonowania każdej kontrolki w formularzu staje się bardzo męczące i męczące, a jeśli ten kod jest zwykle obsługiwany przez projektanta interfejsu użytkownika, nie ma większego znaczenia. ... chyba że interfejs użytkownika jest ułożony dynamicznie lub nie używa względnych pozycji do jakiejś kotwicy lub jest pisany ręcznie. W takim przypadku powiedziałbym, że lepiej jest zdefiniować pewne znaczące stałe dla układu. A jeśli potrzebujesz współczynnika kruszenia tu lub tam, aby wyrównać / ustawić coś „w sam raz”, to również należy zdefiniować.
Ale w twoim przykładzie uważam, że zastąpienie
24 * 60 * 60
przezDAYS_TO_SECONDS_FACTOR
jest lepsze.Przyznaję, że wartości zakodowane są również OK, gdy kontekst i użycie są całkowicie jasne. Jest to jednak wezwanie do osądu ...
Przykład:
Jak wskazał @rmx, użycie 0 lub 1 w celu sprawdzenia, czy lista jest pusta, czy może w granicach pętli jest przykładem przypadku, w którym cel stałej jest bardzo jasny.
źródło
0
lub, jak1
sądzę, używać .if(someList.Count != 0) ...
jest lepszy niżif(someList.Count != MinListCount) ...
. Nie zawsze, ale ogólnie.Przestań, gdy nie możesz przypisać znaczenia ani celu numerowi.
jest znacznie łatwiejszy do odczytania niż zwykłe używanie liczb. (Chociaż można by to uczynić bardziej czytelnym dzięki pojedynczej
SECONDS_PER_DAY
stałej, ale jest to zupełnie osobny problem).Załóżmy, że programista patrząc na kod może zobaczyć, co robi. Ale nie zakładaj, że oni również wiedzą dlaczego. Jeśli twoja stała pomaga zrozumieć, dlaczego? Jeśli nie, nie rób tego.
Jeśli skończy się zbyt wiele stałych, jak sugerowała jedna odpowiedź, rozważ użycie zewnętrznego pliku konfiguracyjnego, ponieważ posiadanie dziesiątek stałych w pliku nie poprawia dokładnie czytelności.
źródło
Prawdopodobnie powiedziałbym „nie” takim rzeczom jak:
I zdecydowanie powiedziałbym „nie”:
źródło
Jednym z najlepszych przykładów, jakie znalazłem w celu promowania używania stałych do oczywistych rzeczy, takich jak
HOURS_PER_DAY
:Obliczaliśmy, jak długo rzeczy leżą w kolejce do pracy. Wymagania zostały luźno zdefiniowane, a programator zakodowany
24
na stałe w wielu miejscach. W końcu zdaliśmy sobie sprawę, że niesprawiedliwe jest karanie użytkowników za siedzenie na problemie przez 24 godziny, podczas gdy naprawdę działa tylko przez 8 godzin dziennie. Gdy przyszło zadanie, aby to naprawić ORAZ zobaczyć, jakie inne raporty mogą mieć ten sam problem, bardzo trudno było grep / przeszukać kod 24, byłoby znacznie łatwiej grep / przeszukaćHOURS_PER_DAY
źródło
Myślę, że dopóki liczba jest całkowicie stała i nie ma możliwości zmiany, jest całkowicie akceptowalna. Więc w twoim przypadku
seconds = num_days * 24 * 60 * 60
jest w porządku (zakładając oczywiście, że nie robisz czegoś głupiego jak wykonywanie tego rodzaju obliczeń w pętli) i jest prawdopodobnie lepsza dla czytelności niżseconds = num_days * HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE
.Kiedy robisz takie rzeczy, to źle:
lineOffset += 24; // 24 lines to a page
Nawet jeśli nie możesz już zmieścić wierszy na stronie lub nawet jeśli nie masz zamiaru go zmieniać, użyj zamiast tego stałej zmiennej, ponieważ pewnego dnia wróci cię prześladować. Ostatecznie chodzi o czytelność, a nie oszczędzenie 2 cykli obliczeń na CPU. To nie jest już rok 1978, kiedy cenne bajty zostały wyciśnięte z całej ich wartości.
źródło
Jest całkowicie w porządku. To nie są tak naprawdę magiczne liczby, ponieważ nigdy się nie zmienią.
Wszelkie liczby, które mogą się w uzasadniony sposób zmienić lub nie mają oczywistego znaczenia, powinny być umieszczone w zmiennych Co oznacza prawie wszystkie z nich.
źródło
seconds = num_days * 86400
nadal byłby do przyjęcia? Gdyby taka wartość była używana wielokrotnie w wielu różnych plikach, w jaki sposób sprawdziłbyś, czy ktoś nie przypadkowo wpisałseconds = num_days * 84600
w jednym lub dwóch miejscach?Unikałbym tworzenia stałych (wartości magicznych) w celu konwersji wartości z jednej jednostki na drugą. W przypadku konwersji wolę nazwę metody mówionej. W tym przykładzie byłoby to np.
DayToSeconds(num_days)
Wewnętrzne, że metoda nie potrzebuje magicznych wartości, ponieważ znaczenie „24” i „60” jest jasne.W takim przypadku nigdy nie użyłbym sekund / minut / godzin. Używałbym tylko TimeSpan / DateTime.
źródło
Użyj kontekstu jako parametru do podjęcia decyzji
Na przykład masz funkcję o nazwie „replaceSecondsBetween: aDay and: anotherDay”, nie będziesz musiał wiele wyjaśniać, co robią te liczby, ponieważ nazwa funkcji jest dość reprezentatywna.
Kolejne pytanie brzmi: jakie są możliwości obliczenia go w inny sposób? Czasami istnieje wiele sposobów na zrobienie tego samego, więc aby pomóc przyszłym programistom i pokazać im, jakiej metody użyłeś, zdefiniowanie stałych może pomóc to rozgryźć.
źródło