Czy zasada stylu kodowania - np. Zasada pojedynczego wyjścia - naprawdę jest dobra? Zawsze czy tylko czasami? Ile to naprawdę robi różnicę?
Bez względu na twoje opinie, są to oczywiście subiektywne pytania. Albo czy oni?
Czy ktoś próbował przeprowadzić obiektywne, rygorystyczne naukowo badanie zasad stylu kodowania?
Nie mogę sobie wyobrazić, jak ktoś mógłby przeprowadzić podwójnie ślepe badanie czytelności, ale być może może być możliwa podwójna ignorancja - wykorzystaj studentów, którzy nie wiedzą o zasadzie studiowanej jako przedmioty, oraz osoby niebędące programistami do zarządzania badaniem.
coding-style
Steve314
źródło
źródło
single-exit principle
tak naprawdę nie dotyczy C ++ z powodu RAIIbreak
,goto
lubreturn
robić. Pojedyncze wyjście IOW nie jest absolutne w C ++, ale to w zasadzie mój pogląd na C w większości innych języków. Ale nadal jest to istotne w nieokreślonym sensie.Odpowiedzi:
Powtarzam komentarz deadalnix: przeczytaj Kod Complete 2 . Autor (Steve McConnell) szczegółowo omawia styl kodowania i często odwołuje się do artykułów i danych.
źródło
Bardzo wątpię w samą możliwość przeprowadzenia badań na ten temat, które przyniosłyby obiektywne wyniki i pozostanę sceptyczny, dopóki nie zostaną mi pokazane przekonujące badania.
Programiści, którzy spędzili lata czytając i pisząc kod zgodny z pewnym stylem kodowania, z pewnością uznają go za bardziej czytelny niż jakiś idealny styl kodowania, który zobaczyliby po raz pierwszy w życiu.
Jest dokładnie tak samo z najpopularniejszym układem pisania QWERTY - łatwo jest udowodnić, że jest dość nieoptymalny pod względem ergonomii (czy uważasz, że wszystkie znaki słowa TYPEWRITER zostały umieszczone w górnym rzędzie, mając na uwadze naszą codzienną wygodę?) .
Ale ulepszone alternatywy, takie jak Dvorak lub Colemak, nigdy się nie przyjęły i jest mało prawdopodobne. Dlatego ludzie nie są z nimi bardziej produktywni - fakt. Nawet jeśli są lepsi w jakimś abstrakcyjnym sensie.
Ponadto trudno byłoby znaleźć osoby bez wcześniejszego kontaktu z programowaniem (ponieważ mogłoby to zaszkodzić wynikom naszego badania), ALE umiejętności programowania, ORAZ chęć uczestnictwa w badaniu przez okres wystarczająco długi, aby wykazać oba krótkie - świadczenia czasowe i świadczenia długoterminowe, aby można je było porównać ze sobą ... (Nie wiem, czy wykluczają się wzajemnie, ale badacze nie mogli po prostu założyć, że nigdy nie są).
źródło
Odpowiedź jest ostateczna NIE! Czy „złam” i „kontynuuj” złe praktyki programowania? jest podzbiorem tego pytania, więc zacznę od ledwie zmodyfikowanej odpowiedzi na to ...
Możesz [ponownie] pisać programy bez instrukcji break (lub wraca ze środka pętli, które robią to samo). Ale może to wymagać wprowadzenia dodatkowych zmiennych i / lub powielania kodu, które zwykle utrudniają zrozumienie programu. Z tego powodu Pascal (język programowania z końca lat 60.) był bardzo zły, szczególnie dla początkujących programistów.
Istnieje wynik informatyki zwany hierarchią struktur kontrolnych Kosaraju, która sięga 1973 roku i jest wspomniana w (bardziej) znanym artykule Knutha Programowanie strukturalne wraz z oświadczeniami z 1974 roku. To, co S. Rao Kosaraju udowodnił w 1973 roku, to że nie jest możliwe jest przepisanie wszystkich programów z wielopoziomowymi podziałami głębokości n na programy z głębokością przerwania mniejszą niż n bez wprowadzania dodatkowych zmiennych. Powiedzmy jednak, że jest to wynik czysto teoretyczny. (Po prostu dodaj kilka dodatkowych zmiennych ?! Z pewnością możesz to zrobić, aby poczuć się w grupie z użytkownikami 3K + na stosie wymiany ...)
O wiele ważniejsze z punktu widzenia inżynierii oprogramowania jest najnowszy artykuł Erica S. Robertsa z 1995 r. Zatytułowany Loop Exits and Structured Programming: Reopening the Debate (doi: 10.1145 / 199688.199815). Roberts podsumowuje kilka badań empirycznych przeprowadzonych przez innych przed nim. Na przykład, gdy grupa studentów typu CS101 została poproszona o napisanie kodu dla funkcji realizującej wyszukiwanie sekwencyjne w tablicy, autor badania powiedział o tych studentach, którzy użyli przerwy / powrotu, aby wyjść z sekwencji pętla wyszukiwania zaraz po znalezieniu elementu:
Roberts mówi również, że:
Tak, możesz być bardziej doświadczony niż studenci CS101, ale bez użycia instrukcji break (lub równoważnie return / goto ze środka pętli), w końcu napiszesz kod, który przy nominalnej ładnej strukturze jest wystarczająco włochaty pod względem dodatkowej logiki zmienne i powielanie kodu, że ktoś, prawdopodobnie ty, wprowadzi do niego błędy logiczne, próbując podążać za pewnym pomysłem „poprawnego” stylu kodowania.
Jest tu jeszcze jeden większy problem oprócz instrukcji return / break-type, więc to pytanie jest nieco szersze niż pytanie o breakach. Według niektórych mechanizmy obsługi wyjątków również naruszają paradygmat punktu wyjścia
Tak więc w zasadzie każdy, kto twierdził powyżej, że zasada jednokrotnego wyjścia jest nadal przydatna, również przeciwstawia się paradygmatowi obsługi wyjątków, chyba że zostanie zastosowany w niezwykle zawężający sposób opisany w tym ostatnim linku; wytyczne te zasadniczo ograniczają wszystkie wyjątki poza funkcję throw (), tzn. propagacja wyjątków międzyfunkcyjnych jest w ogóle niedozwolona. Ciesz się nowym Pascalem dzięki składni podobnej do C ++.
Widzę, skąd wzięło się pojęcie „tylko jeden powrót”?że powszechna opinia na tej stronie jest sprzeczna z tym, co tu zamieściłem, więc w pełni rozumiem, dlaczego zostałem już poddany głosowaniu w dół, mimo że jestem pierwszą odpowiedzią na to pytanie, o którą pytam: kilka informacji na temat rzeczywistych testów użyteczności skoncentrowanych na problemie pojedynczego wyjścia. Chyba nie powinienem pozwolić, aby wiedza przeszkadzała w uprzedzeniach, szczególnie na stronie grywalizacji. Odtąd będę trzymał się edycji Wikipedii. Doceniane są przynajmniej informacje pochodzące z dobrych źródeł, a niejasne lub niepoprawne twierdzenia, które udają, że są poparte źródłami, ostatecznie zostają zablokowane. Na tej stronie dzieje się coś wręcz przeciwnego: dominują opinie niepoparte dowodami. Spodziewam się, że moda usunie tę ostatnią część, ale przynajmniej ten koleś będzie wiedział, dlaczego straciłeś mnie na zawsze jako współpracownik.
źródło
http://dl.acm.org/citation.cfm?id=1241526
http://www.springerlink.com/content/n82qpt83n8735l7t/
http://ieeexplore.ieee.org/xpl/freeabs_all.jsp?arnumber=661092
[Wydaje się, że na twoje pytania odpowiada jedno słowo „tak”. Powiedziano mi jednak, że udzielanie krótkich odpowiedzi jest „lekceważące” dla pytania. Jeśli uważasz, że byłem lekceważący, oznacz flagę, aby moderator mógł ją usunąć.]
źródło
Is a coding style principle - e.g. the single-exit principle - really a good thing?
- daje kontekst pytaniu, które stawia, o stylach kodowania. Co więcej, styl kodowania nie jest taki sam jak metodologia programowania, w szczególności metody projektowania wysokiego poziomu, na których skupia się artykuł IEEE (wyraźnie stwierdzony przez autorów). Dlatego mówię „nie” - zakresy są zupełnie inne.Ludzie, którzy wciąż zastanawiają się, czy wybrać jedno wyjście, czy wiele wyjść, wciąż utknęli pod koniec lat sześćdziesiątych. Wówczas taka dyskusja była ważna, ponieważ byliśmy w początkowej fazie ustrukturyzowanego programisty, a obóz głosił, że ustalenia stojące za twierdzeniem o programie strukturalnym Bohm-Jacopini nie były uniwersalne dla wszystkich konstrukcji programistycznych.
Jest to coś, co powinno być uregulowane dawno temu. Cóż, zostało to ustalone (dokładnie 4 dekady, zarówno w środowisku akademickim, jak i w branży), ale ludzie (ci, którzy są absolutnie za lub przeciw) nie zwracają na to uwagi.
Co do reszty moich odpowiedzi, wszystko jest względne (czego nie ma w oprogramowaniu?):
Tak. Przez większość czasu na ogólny przypadek, z zastrzeżeniami specyficznymi dla przypadków skrajnych i konstrukcjami programistycznymi specyficznymi dla języka.
Większość czasu.
Zależy.
Czytelny kod a nieczytelny kod. Zwiększona złożoność (którą powinniśmy już wiedzieć, zwiększa prawdopodobieństwo wprowadzenia błędów) w porównaniu z prostszą złożonością (i ergo, mniejsze prawdopodobieństwo błędów.) Języki, których kompilatory nie dodają ukrytego zwrotu (powiedzmy, Pascal, Java lub C #) i te, które domyślnie int (C i C ++).
Ostatecznie jest to umiejętność doskonalona przez liczbę godzin pracy za klawiaturą. Czasami dobrze jest mieć wiele instrukcji return, takich jak tutaj (w niektórych pseudokodach Pascala):
Cel jest jasny, a algorytm jest wystarczająco mały i na tyle nieskomplikowany, że nie gwarantuje stworzenia zmiennej „flagowej”, która przechowuje ewentualną wartość zwrotną używaną w jednym punkcie zwrotnym. Algorytm może być błędny, ale jego struktura jest na tyle prosta, że wysiłek w wykryciu błędu jest (najprawdopodobniej) znikomy.
Czasami tak nie jest (tutaj przy użyciu pseudokodu C):
W tym przypadku algorytm nie ma prostej struktury, a instrukcja switch (w stylu C) pozwala na kroki przejściowe, które mogą, ale nie muszą być celowo wykonywane jako część algorytmu.
Być może algorytm jest poprawny, ale źle napisany.
A może przez siły zewnętrzne przekraczające możliwości programisty jest to rzeczywista (i poprawna) reprezentacja prawnie potrzebnego algorytmu.
Może to źle
Odkrywanie prawdy w tym wszystkim wymaga znacznie więcej wysiłku niż w poprzednim przykładzie. I tu leży coś, w co mocno wierzę (pamiętajcie, że nie mam formalnych badań, które mogłyby to poprzeć):
Zakładając poprawny fragment kodu:
Wiele instrukcji return zwiększa czytelność i prostotę takiego fragmentu kodu, jeśli fragment ten reprezentuje prosty algorytm o z natury prostej strukturze przepływu. Mówiąc prościej, nie mam na myśli małych, ale rozumiem z natury zrozumiałe lub samo-dowody , które nie wymagają nieproporcjonalnego wysiłku w czytaniu (ani nie nakłaniają ludzi do wymiotowania, przeklinania czyjejś matki lub połykania kuli, gdy muszą ją przeczytać. )
Pojedyncza instrukcja return zwiększa czytelność i prostotę takiego fragmentu kodu, jeśli wartość zwracana jest albo obliczana podczas wykonywania algorytmu, albo jeśli kroki w algorytmie odpowiedzialnym za obliczenie można zgrupować w jednym miejscu w strukturze algorytmu .
Pojedyncza instrukcja return zmniejsza czytelność i prostotę takiego fragmentu kodu, jeśli wymaga przypisania do jednej lub więcej zmiennych flag, przy czym lokalizacje takich przypisań nie są jednolicie rozmieszczone w całym algorytmie.
Wiele instrukcji return zmniejsza czytelność i prostotę takiego fragmentu kodu, jeśli instrukcje return nie są równomiernie rozmieszczone w algorytmie i jeśli wyznaczają wzajemnie wykluczające się bloki kodu, które nie są jednorodne pod względem wielkości lub struktury między sobą.
Jest to ściśle związane ze złożonością fragmentu kodu, o którym mowa. A to z kolei wiąże się z miarami złożoności cyklicznej i halsteadowej. Na tej podstawie można zaobserwować:
Im większy rozmiar podprogramu lub funkcji, tym większa i bardziej złożona jest jej struktura przepływu kontroli wewnętrznej, a tym większe prawdopodobieństwo, że staniesz przed pytaniem, czy użyć instrukcji wielokrotnego, czy pojedynczego zwrotu.
Wniosek z tego jest następujący: utrzymuj małe funkcje, robiąc jedną rzecz i tylko jedną rzecz (i robiąc to dobrze). Jeśli wykażą nominalnie małe wskaźniki złożoności cyklicznej i półstrzałowej, to nie tylko będą prawdopodobnie najprawdopodobniej poprawne i będą realizacją zrozumiałych zadań, ich wewnętrzne struktury również będą stosunkowo oczywiste.
Wtedy, i tylko wtedy możesz dość łatwo i nie tracąc dużo snu, możesz zdecydować, czy użyć pojedynczego zwrotu i wielu zwrotów bez większego ryzyka wprowadzenia błędów przy którymkolwiek z tych wyborów.
Można również spojrzeć na to wszystko i zasugerować, że gdy ludzie zmagają się z problemem pojedynczych zwrotów lub wielokrotnych zwrotów, dzieje się tak dlatego, że - albo z powodu braku doświadczenia, głupoty, albo braku etyki pracy - nie piszą czystego kodu i mają tendencję do pisania potworne funkcje z całkowitym lekceważeniem miar cyklicznych i halsztowych.
źródło