Czasami algorytm można zapisać na dwa sposoby:
- Krótki, fantazyjny sposób; lub
- Dłuższy, łatwy do zrozumienia sposób.
Na przykład, tutaj jest dłuższy, łatwiejszy sposób kopiowania łańcucha source
do dest
C:
*dest = *source;
while (*source != '\0') {
source++;
dest++;
*dest = *source;
} (true);
A oto krótki, fantazyjny sposób.
// Copy string source to dest
while (*dest++ = *source++);
Zawsze słyszałem i czytałem, że należy unikać wymyślnego kodu i zazwyczaj się zgadzam. Ale co, jeśli weźmiemy pod uwagę komentarze? Załóżmy, że podobnie jak w powyższych przykładach mamy niepomentowany, dłuższy i rzekomo łatwiejszy do zrozumienia kod oraz dobrze skomentowany, krótki, fantazyjny kod? Czy nadal nie jest pożądany kod?
EDYCJA: Wielu skomentowało nazwy zmiennych, więc zmodyfikowałem przykładowy kod, aby nie uczynić tego czynnikiem, gdy wolę nad innymi. Próbowałem usunąć podwójne przypisanie w pierwszym przykładzie, ale to tylko uczyniło kod mniej czytelnym.
Być może nie był to najlepszy z przykładów, ponieważ wielu uważa, że „fantazyjny” kod jest bardziej czytelny i zrozumiały niż dłuższy kod. Chodziło o to, aby mieć jeden dłuższy kod, który był znacznie łatwiejszy do zrozumienia niż bardzo krótki, ale skomplikowany kod.
EDIT2: Oto nowy przykład, który dostałem od SO :
Skomentowana fantazyjna wersja:
//direct formula for xoring all numbers from 1 to N
int Sum = (N & (N % 2 ? 0 : ~0) | ( ((N & 2)>>1) ^ (N & 1) ) );
Długa wersja bez komentarza:
int Sum = 0;
for (int i = 1; i < N; ++i)
{
Sum ^= i; //or Sum = Sum ^ i;
}
Odpowiedzi:
Generalnie wolałbym wyodrębnić fantazyjny kod we własnej metodzie.
Zamiast komentować wymyślny kod, nazwa metody powinna być wszystkim, czego potrzeba, aby wszystko było jasne.
źródło
Jestem za dłuższą wersją. Problem z krótką wersją kodu, poza tym, że jest trudniejszy do odczytania dla niektórych programistów, polega na tym, że przez większość czasu trudniej jest dostrzec błędy, patrząc na nie.
Mam przykład z prawdziwego życia. W naszym produkcie mieliśmy następujący fragment kodu:
Ten kod na pierwszy rzut oka wygląda zupełnie rozsądnie, ale po długim czasie ten licznik przepełnia się i psuje warunek (w prawdziwym scenariuszu zmiażdżyliśmy system produkcyjny naszego klienta OOM). Ten kod jest nieco mniej „wyrafinowany”, ale jasne jest, że robi to, co powinien:
I możesz powiedzieć, że programista, który napisał ten kod, po prostu nie był wystarczająco dobry (co nie jest prawdą, był raczej bystry), ale myślę, że jeśli twoja technika kodowania wymaga od ciebie umiejętności programowania w trybie super-duper BOGA w aby uzyskać poprawny kod, robisz coś złego. Twój kod powinien być jak najbardziej głupi ze względu na ciebie i dla każdego, kto musi zachować ten kod po tobie (który może nie być tak mądry jak ty).
Więc - jestem za prostotą i jasnością.
Edycja: Aha, a jeśli chodzi o komentarze - to nie ma znaczenia. Wiele osób i tak nie przeczyta komentarzy ( http://www.javaspecialists.co.za/archive/Issue039.html ), a ci, którzy nie zrozumieją Twojego kodu bez komentarzy, nie zrozumieją go wystarczająco dobrze, aby mogli mogę to utrzymać. Celem jest, aby pomóc ludziom zobaczyć, że określony kod jest „poprawny”, komentarze nie mogą w tym pomóc.
źródło
Ogólnie wolałbym dłuższą wersję. Przychodzą mi na myśl dwa główne powody:
Dla najlepszego z obu światów, zawiń kod w funkcję, której nazwa komentuje za Ciebie:
Jedynym powodem, aby tego nie robić, byłby problem z wydajnością, a profilowanie rzeczywiście pokazało, że narzut funkcji jest znaczący.
źródło
Cokolwiek jest najczystsze. Często jest to kompaktowy, łatwy do zrozumienia fragment kodu, który nie wymaga komentarza ... jak twój drugi przykład.
Zasadniczo krótsze fragmenty kodu są łatwiejsze do zrozumienia, ponieważ czytelnik ma mniej czasu na głowie. Oczywiście jest limit, kiedy kod jest nadmiernie zaciemniony i nie mam na myśli tego, że białe pola zwiększające przejrzystość powinny zostać przycięte.
Komentarze nigdy nie powinny zawierać niczego, co jest oczywiste z kodu, co tylko sprawia, że czytelnik czyta to samo dwa razy. Dla mnie pierwszy fragment wymaga wyjaśnienia. Dlaczego programista nie użył
do...while
pętli do usunięcia duplikatu*s = *t;
zadania? Muszę przeanalizować więcej kodu, aby zdać sobie sprawę, że implementuje kopię ciągu. Komentarz byłby bardziej pomocny w przypadku dłuższego kodu niż krótszego.Komentarz do drugiego fragmentu jest prawie zbędny, ponieważ podczas gdy pętla jest praktycznie idiomatyczna, ale mówi, co robi kod na wyższym poziomie niż sam kod, co czyni go użytecznym komentarzem.
źródło
do ... while
po prostu dlatego, że nie pomyślałem o tym, kiedy napisałem pytanie. Dzięki za zwrócenie na to uwagi. ^^ Drugi fragment może być dla ciebie oczywisty, ale z pewnością nie jest dla mnie.Problem polega na tym, że nie ma jasnej definicji,
short fancy code
ponieważ zależy to bardzo od poziomu programisty. Podczas gdy niektórzy ludzie nie mają problemu ze zrozumieniemwhile(*s++ = *t++);
wyrażenia, inni tak.Osobiście uważam, że jest on
while(*s++ = *t++);
doskonale czytelny, a dłuższy jest trudniejszy do odczytania. Inni mogą się jednak nie zgodzić.Niezależnie od tego, chodzi tylko o zdrowy rozsądek. Czytelność powinna zdecydowanie być priorytetem, ale jest taki moment, w którym dłuższy kod staje się mniej czytelny, gdy staje się dłuższy. Szczegółowość często zmniejsza czytelność z mojego doświadczenia.
źródło
Nie zgadzam się z większością innych odpowiedzi tutaj - myślę (przynajmniej w tym przypadku), że krótszy kod jest lepszy. Wbrew twierdzeniom, dłuższy kod nie jest „łatwiejszy”, przynajmniej dla czytelnika. Jeśli już, wydaje się, że przestałeś chcieć wydłużyć go, nawet jeśli utrudnia to zrozumienie kodu i / lub zapewnienie prawidłowego działania.
W szczególności, przypisanie pierwszego bajtu łańcucha poza pętlę, oddzielne od przypisania dla innych bajtów, oznacza, że trzeba być znacznie bardziej ostrożnym w czytaniu, aby mieć pewność, że wszystkie bajty zostały poprawnie skopiowane. Podstawowa sekwencja działań w krótszej wersji jest znacznie łatwiejsza do zweryfikowania. Jedynym prawdziwym problemem jest formatowanie - gdy masz celowo puste ciało pętli, najlepiej to wyjaśnić, na przykład:
lub nawet:
Niektóre osoby wolą zamiast tego używać nawiasów klamrowych:
Bez względu na to, jakie preferujesz formatowanie, popełniono wystarczająco dużo błędów, takich jak:
... że ważne jest, aby mieć pewność, że 1) oczywiste jest, co jest właściwie kontrolowane przez dowolną kontrolę przepływu, oraz 2) oczywiste jest, że kod został napisany, wiedząc, co jest kontrolowane przez niego, więc ktoś go czytający nie marnuje czasu na próby aby dowiedzieć się, czy właśnie znaleźli błąd.
źródło
Upewnij się, że każdy inny programista rozumie, co robi Twój kod - a nawet lepiej, jeśli jest na pierwszy rzut oka (w tym miejscu pojawiają się dobre nazwy i komentarze).
Fantazyjne kręcenie bitów kung-fu i inline montaż są świetne w imię (być może niepotrzebnej i przedwczesnej) optymalizacji, ale kiedy nawet nie możesz zrozumieć kodu, który napisałeś, gdy napotkasz w nim błąd dwa miesiące później ... Jaki był sens? Będziesz kosztować siebie czas i wysiłek.
W takich sytuacjach często odnoszę się do Zen Pythona . W szczególności:
źródło
Nie pisz wyszukanego kodu w oprogramowaniu produkcyjnym. Wiem, że dobrze jest móc to napisać i jest krótsza. Pisanie fantazyjnego kodu znacznie zwiększa wartość „WTF / minutę”, innymi słowy obniża jakość.
źródło
To oczywiście całkowicie zależy od okoliczności. ale ogólnie uważam, że jest to dobra zasada:
~ Brian Kernighan
źródło
Z mojego doświadczenia wynika, że największą wygraną, jeśli chodzi o krótki wymyślny kod, jest raczej rekurencja niż iteracja. Jest to również jedna z najtrudniejszych rzeczy do zrozumienia na pierwszy rzut oka, chyba że pracujesz w języku, w którym wszystko jest rekurencyjne. Nadal będę go faworyzować za elegancję i szybkość rozwoju, jakie oferuje, ale staram się, aby miał szczegółowe komentarze, jeśli wygląda na to, że będzie nieprzejrzysty dla przyszłych opiekunów lub mojego przyszłego ja.
źródło
Zaczynam nigdy nie ufać komentarzom. Zbyt często komentarze nie są aktualizowane, gdy kod jest aktualizowany, i są znacznie nieaktualne lub reprezentują reguły od klientów / kierownictwa, które już nie są istotne.
Doszło do tego, że w niektórych przypadkach komentarze nawet nie pasują do kodu, który opisują.
Jeśli muszę wybierać między krótkim / fantazyjnym a dłuższym / łatwiejszym do zrozumienia, zawsze wybieram ten drugi, chyba że tak naprawdę jest dobry powód.
źródło
Czytelność i łatwość konserwacji są kluczowe, a twój drugi przykład (tj. Dłuższy) to znacznie więcej. Ale po co ograniczać się do dwóch opcji? Nawet dłuższy kod jest zbyt skomplikowany (IMHO), aby nie notować dalej. Umieściłbym to w swojej własnej metodzie z odpowiednim Javadoc (lub czymkolwiek) i odpowiednią nazwą metody.
źródło