Skocz do zawartości
GAndaLF

[Programowanie] Sekrety profesjonalnego programowania

Pomocna odpowiedź

"Obyś pracował z cudzym kodem" to taki odpowiednik "Obyś uczył cudze dzieci" 😉

Ja bym dodał do powyższego jeszcze jedno: starajcie się rozdzielać kod, który może być niezależny od platformy od tego zależnego jeśli piszecie na mikrokontrolery lub piszecie coś co na różnych systemach operacyjnych robi się inaczej.

Z przewijaniem bywa różnie. Ja np. uważam za bardzy zły zwyczaj wstawianie średników na końcu linii:

if(...){

...

}

zamiast

if(...)

{

...

}

przy dużej liczbie ifów przeplatanych z normalnymi komendami, czytelność kodu leży.

Pamiętajcie też o tym, że każdy kod można poprawić. Każdy! Jedyny problem polega na tym, czy warto poprawiać kod spełniający wszystkie wymagania, skoro zajmuje to często dużo czasu. Reguł jest oczywiście o wiele więcej, ale trzeba lat doświadczenia i nauki, aby dobrze pisać.

Oraz pamiętajcie: jeżeli coś dopisaliście do kodu i zaczyna się wywalać w zupełnie innym miejscu, sprawdźcie wskaźniki 😉

Udostępnij ten post


Link to post
Share on other sites
wstawianie średników

Chyba miałeś na myśli nawiasów 🙂

Oraz pamiętajcie: jeżeli coś dopisaliście do kodu i zaczyna się wywalać w zupełnie innym miejscu, sprawdźcie wskaźniki

Jak ktoś nie skojarzy, to warto również pamiętać o ilości zadeklarowanych elementów w danej tablicy 🙂

Udostępnij ten post


Link to post
Share on other sites

Bardzo fajny artykuł 🙂

Zainteresowanych tematem proszę o zwrócienie uwagi na - moim zdaniem - najlepszą pozycję dotyczącą dobrej praktyki programistycznej jaka ukazała się w Polsce:

Dennie van Tassel "Praktyka Programowania" WNT 1978

Nie jest to jakaś super nowość, ale czyta się ją bardzo fajnie i nieraz otwierałem oczy ze zdumienia mrucząc "O rany, tego typu błędu szukałem 2 tygodnie".

Autor nie skupia się na konkretnych językach programowania (choć podaje też przykłady w COBOLu, FORTRANie, BASICu, C itp), tylko traktując je jako sposób wyrażania pewnego algorytmu pisze o procesie powstawania oprogramowania od założeń, poprzez analizę, kodowanie, uruchamianie i testowanie. Na każdym z tych etapów można popełnić fatalne w skutkach błędy a im dalej w las tym błędy kosztują więcej. Warto więc uczyć się na cudzych i przestrzegać dosłownie tylko kilku reguł podanych tu na talerzu.

Ta książka powinna być obowiązkową lekturą na każdym kursie dowolnego języka programowania. Co ciekawe wciąż dostępna jest na aukcjach (znaczy kupują?) i kosztuje jakieś grosze (mają mało pieniędzy?). Studenci? 🙂

Udostępnij ten post


Link to post
Share on other sites

Bardzo dobrze, że ktoś poruszył taki temat. Studiuję informatykę i nawet tam nikt jasno nie poruszył tego zagadnienia. Każdy musi dochodzić do tego sam, na własnych błędach, albo dowiadywać się z zewnątrz. O ile na informatyce mamy sporo projektów programistycznych i da się dość szybko zrozumieć tego typu problemy, to na kierunkach typu EleTele czy AiR to jakaś tragedia. Zlecają ludziom napisanie symulacji 3D w Javie; w efekcie projekt robi się na kolanie, byle szybciej, byle jakoś działał. Kilkaset linii kodu, wszystko w jednym pliku - od samego przeglądania tego giganta może się odechcieć.

Pod koniec liceum myślałem, że umiem programować bo znam C/C++ i kilka innych języków. Poszedłem na uczelnię i okazało się, że to bzdura. Zresztą pod pojęciem "profesjonalne programowanie" nie kryje się tylko czytelne formatowanie kodu. Stosuje się jeszcze sporo technik, które mają ułatwić pracę w zespole i wzajemną komunikację. Tego nie sposób poznać kodując samemu w domu małe programy konsolowe. Prawdziwe wyzwania zaczynają się gdy idziesz do pracy, dostajesz 2-letni projekt składający się z kilkuset klas i kilkunastu modułów. W dodatku każdy z modułów jest pisany przez innego programistę/programistów. Wtedy ma się do czynienia z wzorcami projektowymi, repozytoriami kodu aby m. in. umożliwić równoległą pracę, bugtrackerami (bazami znanych błędów), testami jednostkowymi (techniki typu Test-Driven Development) itp. itd.. Nawet podział plików projektu na odpowiednie foldery ma ogromne znaczenie.

Piszę to po to żeby uświadomić niektórym początkującym, że warto na początku przycisnąć i uczyć się nie tylko np. jak korzystać z funkcji bibliotecznych dla procesorów STM32, ale jak sprawić by ten kod jakoś wyglądał. Prosty test - weź swój kod sprzed pół roku albo starszy i zobacz czy go rozumiesz. Pewnie, że nie wszystkie te techniki, o których napisałem, znajdą zastosowanie w małych projektach, ale można próbować z nich korzystać aby ułatwić i uprzyjemnić pracę sobie i możliwe, że komuś, kto po Tobie będzie utrzymywał ten kod.

Także tego... Nagadałem się trochę - podsumowując, formatowanie kodu to tylko wierzchołek góry lodowej, ale warto od tego zacząć 🙂

Udostępnij ten post


Link to post
Share on other sites
Zastanówmy się teraz, jakie warunki powinien spełniać gotowy produkt.

Bardzo proste. Mnie uczono tak.

Zasada pierwsza:

Program powinien być tak stworzony aby był, jak to tylko możliwe idioto odporny.

Zasada druga:

Program powinien być, modułowy, czyli łatwy w przebudowie, rozbudowie, co oznacza w skrócie budowę własnych bibliotek.

Zasada trzecia:

Kod programu, ma być dobrze opisany, aby osoba trzecia, mogła się z niego wyznać.

Zasada czwarta:

Instrukcja GOTO - to grzech ciężki.

Zasada piata:

Im mniej zmiennych tym lepiej.

Zasada szósta:

Zmienne tymczasowe, nazywać od słowa Temp, lub ostatecznie Buf.

Zasada siudma:

Zmienne powinny mieć jednoznaczne nazwy, okreslające ich przeznaczenie.

Wiecej grzechów nie pamietam, ale może sobie przypomnę.

Udostępnij ten post


Link to post
Share on other sites
Instrukcja GOTO - to grzech ciężki.

Nie przesadzajmy. GOTO i return bezargumentowy mają w zasadzie podobną funkcję, tylko goto ma większe możliwości. Natomiast trzeba go używać z głową, tzn. odnośnik do goto powinien być w miarę możlwisoći widoczny na tym samym ekranie co samo goto i najlepiej być wyróżniony jakimś komentarzem. I nie więcej niż jedno goto na raz. To mniej więcej tak samo jak z zasadą, że ruszać należy z pierwszego biegu, nie z drugiego. Ale czasami jeśli przestrzeganie tej zasady nastręcza dużo trudności, to jej nie przestrzegamy. Tak samo tutaj. Poza tym są przewinienia znacznie gorsze niż użycie GOTO, jak chociażby (i tutaj pojawai się kolejna reguła) nieprzestrzeganie:

Nie należy używać tzw. Magic numbers. Jeśli przekazujemy do funkcji jakąś liczbę to niech ona będzie odpowiednio nazwana za pomocą #define, a nie, że mamy potem kwiatki w guście:

MyFunction(&SensorData, 2);

MyFunction(&SensorData, 1);

MyFunction(&SensorData, 0);

i nie wiadomo o co chodzi z tymi 0, 1, 2.

Udostępnij ten post


Link to post
Share on other sites

marek1707: W tematyce zalecanych praktyk programistycznych stare książki są wyjątkowo dobre. Prawdopodobnie dlatego, że kiedyś, jak nie było jeszcze środowisk programistycznych kolorujących składnię itp ten problem był jeszcze ważniejszy. Pisząc ten artykuł opierałem się głównie na książce David Straker, "C Style: Standards and Guidelines" z 1991 roku dostępnej za darmo online pod linkiem http://syque.com/cstyle/contents.htm Jednak Twoja książka jest wyjątkowo stara, będę ją musiał przeczytać. Tym bardziej że faktycznie jest dostępna za marne grosze.

GOTO jest bardzo dobre do obsługi błędów i wychodzenia z wielokrotnie zagnieżdżonych konstrukcji. Jednak takie zagnieżdżone konstrukcje zwykle oznaczają, że to nie użycie GOTO jest problemem. Prawdopodobnie cała struktura kodu wymaga głębszej przebudowy. Tak jak OldSkull mówi, jeżeli mamy dobre wytłumaczenie dlaczego używamy GOTO albo łamiemy jakąkolwiek inną zasadę, możemy śmiało to zrobić. Ważne żeby zdawać sobie sprawę z niebezpieczeństw.

Udostępnij ten post


Link to post
Share on other sites

To jak dzielicie projekt na wartwy i moduły? Jak jest realizowana wymiana danych pomiędzy modułamie? Za pomocą zmiennych typu extern czy funkcji void set_var(int *var); oraz int* read_var(void);?

Przykladowo majac w projekcie USART(komunikacja z PC) i I2C(obsługa RTC oraz EEPROM), wówczas projekt podzieliłbym tak:

//ogolne
Main.c
Harddef.h //definicja calego sprzętu
Softdef.h //definicja stalych oglnych do całego programu
GUI.h // definicja np. napisów do LCD
//hardware
HW_i2c.c // inicjalizacja peryferii oraz funkcja przerwania
HW_i2c.h
HW_usart.c // inicjalizacja peryferii oraz funkcja przerwania
HW_usart.h
//modul RTC
RTC_read_time.c
RTC_read_time.h
RTC_set_time.c 
RTC_set_time.h
//modul EEPROM
EE_read_data.c
EE_read_data.h
EE_write_data.c
EE_write_data.h
//modul PC
PC_send_data.c
PC_send_data.h

Wymiane danych pomiedzy modulami lub warstwami zrobilbym dla każdej zmiennej za pomoca funkcji inline void set_var(int *var); oraz int* read_var(void);

Robicie podobnie? Jakie macie metody?

Udostępnij ten post


Link to post
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »

×