• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Dobre praktyki w programowaniu - C++

Object Storage Arubacloud
–1 głos
223 wizyt
pytanie zadane 21 stycznia 2021 w C i C++ przez Whiskey_Taster Pasjonat (15,610 p.)

Cześć! 

Aktualnie piszę program generujący dane do bazy danych i natrafiłem na problem, którego sam nie rozwiążę, ponieważ nie mam dostatecznego doświadczenia. 
Otóż zastanawiam się, co w programowaniu jest lepsze, a raczej w jakich sytuacjach używać określonych typów funkcji. Mam funkcję, która wygląda tak
 

// funkcja nr 1
void getNameAndSurname(QFile& nameFile, QFile& surnameFile, QString& name, QString& surname)
{
    // get random numbers for name and surname
    int name_num = QRandomGenerator::global() -> bounded(1, getFileRowNum(nameFile));
    int sur_num = QRandomGenerator::global() -> bounded(1, getFileRowNum(surnameFile));
    // open files and check
    if (nameFile.open(QIODevice::ReadOnly | QIODevice::Text) && surnameFile.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        QTextStream inName(&nameFile);
        QTextStream inSurname(&surnameFile);
        // go to choosen line
        for (int i = 1; i < name_num; i++)
        {
            inName.readLine();
        }
        name = inName.readLine();
        // go to choosen line
        for (int i = 1; i < sur_num; i++)
        {
            inSurname.readLine();
        }
        surname = inSurname.readLine();
        // close files
        nameFile.close();
        surnameFile.close();
    }
}

Przekazujemy przez referencję dwa pliki z danymi (z imionami i nazwiskami) oraz przez referencję przekazujemy zmienne, w których wyląduje jakieś imię i nazwisko wybrane z pliku. 
Złapałem się jednak na tym, że masa podobnych funkcji wprowadza nieład, to jest używanie samych void'ów sprawi, że niekiedy nie wiadomo, co ta funkcja tak w zasadzie robi, co modyfikuje. 
Wobec tego chciałem rozbić tę funkcję na dwie:
 

// funkcja nr 2.1
QString getName(bool gender)
{
    QFile name_file;
    if (gender)
    {
         name_file.setFileName("D:\\Qt\\Dane\\dane\\PersonalData\\name_man");
    }
    else
    {
        name_file.setFileName("D:\\Qt\\Dane\\dane\\PersonalData\\name_woman");
    }
    int name_num = QRandomGenerator::global() -> bounded(1, getFileRowNum(name_file));
    if (name_file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        QTextStream in(&name_file);
        for (int i = 1; i < name_num; i++)
        {
            in.readLine();
        }
        return in.readLine();
    }
    else
        return 0;
}

oraz

// funkcja nr 2.2
QString getSurname(bool gender)
{
    QFile name_file;
    if (gender)
    {
         name_file.setFileName("D:\\Qt\\Dane\\dane\\PersonalData\\surname_man");
    }
    else
    {
        name_file.setFileName("D:\\Qt\\Dane\\dane\\PersonalData\\surname_woman");
    }
    int name_num = QRandomGenerator::global() -> bounded(1, getFileRowNum(name_file));
    if (name_file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        QTextStream in(&name_file);
        for (int i = 1; i < name_num; i++)
        {
            in.readLine();
        }
        return in.readLine();
    }
    else
        return 0;
}

W nich w zależności od płci wybierany byłby inny plik i zwracalibyśmy odpowiednio imię/nazwisko. Tylko jak widzimy, kod funkcji typu void jest znacznie krótszy, ponieważ funkcje getName() oraz getSurname() są niemal identyczne, różnią się tylko nazwami plików, wobec tego mógłbym to jeszcze skrócić do:
 

// funkcja nr 3
QString getData(bool gender, QString path)
{
    QFile file;
    if (gender)
    {
         file.setFileName(path);
    }
    else
    {
        file.setFileName(path);
    }
    int name_num = QRandomGenerator::global() -> bounded(1, getFileRowNum(name_file));
    if (file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        QTextStream in(&name_file);
        for (int i = 1; i < name_num; i++)
        {
            in.readLine();
        }
        return in.readLine();
    }
    else
        return 0;
}

Wtedy jednak nazwa funkcji nie mówi o tym, co ta funkcja robi, jest to raczej coś ogólnego - dane. 

Tak więc moje pytanie brzmi: w jakich sytuacjach lepiej stosować funkcję nr 1, a w jakich funkcję nr 2.1 i 2.2? A może zamiast nr 2.1 i 2.2 wystarczy nr 3? W dodatku czy przekazywanie dużej ilości parametrów do funkcji jest dobrą opcją? Tutaj mam maksymalnie 4 parametry, jednakże w innej funkcji wychodzi mi ich o kilka więcej, a to już wydaje mi się za dużo. 
 Jak się w tym nie pogubić? Nigdy jeszcze nie widziałem dużego programu (a nawet małego), który ma sporo funkcji i w moim programie pojawił się nieład, który staram się uporządkować. Tak więc wszelkie odpowiedzi na temat używania funkcji mile widziane :)

2
komentarz 21 stycznia 2021 przez tkz Nałogowiec (42,000 p.)
Dwie rzeczy, trzymaj się jednej konwencji, jeżeli funkcja przyjmuje bool'a, to znaczy, że robi za dużo. Zwracanie 0, czy innych cyfr sygnalizujących błąd... To nie jest C. Masz wyjątki, masz std::optional(i pewnie Qt'owy odpowiednik). Sam post, przynajmniej dla mnie, za długi.
komentarz 21 stycznia 2021 przez Whiskey_Taster Pasjonat (15,610 p.)
Wiem, post jest przydługi, ale chciałem poprzeć to konkretnym przykładem, żeby nie było samego gdybania. Z tym zwracaniem 0 to wiem, napisałem to na szybko, a że dopiero się uczę Qt, to nie szukałem czegoś bardziej wyrafinowanego.

Co do konwencji - innymi słowy jeśli już zacząłem robić funkcje typu void i przekazywać argumenty przez referencję, to najlepiej będzie taką praktykę kontynuować? I tylko tyle?
1
komentarz 21 stycznia 2021 przez tkz Nałogowiec (42,000 p.)
Nie. Funkcje i przekazywanie do nich robisz według wymagań. Myślałem o nazewnictwie, raz camel case, raz snake case. Komentarze są dość wrażliwym tematem, wolę go nie poruszać.
komentarz 21 stycznia 2021 przez Whiskey_Taster Pasjonat (15,610 p.)
Okej, wobec tego skoro ja nie mam żadnych wymagań, gdyż jest to coś, co robię na własną rękę, dla treningu, to nie ma metody lepszej lub gorszej.
Uczyłeś się o takich zasadach z jakiegoś konkretnego źródła, czy może doświadczenie zawodowe?
2
komentarz 21 stycznia 2021 przez tkz Nałogowiec (42,000 p.)
Na pewno są puryści, którzy będą walczyć o czystość i ogólno przyjęte normy. Na pewno jeżeli możesz przekazuj przez referencję z modyfikatorem const. Funkcje twórz tak, by były maksymalnie małe, spójne, nie wymagały komentarzy. Mimo, że robisz coś na własną ręke, to nawyki zostają.

Czysty kod w C++17. Oprogramowanie łatwe w utrzymaniu i Czysty kod. Podręcznik dobrego programisty.

Z czego autor pierwszej książki odwołuje się do drugiej. W mojej ocenie pierwsza pozycja jest bardziej przystępna. Wszystkie ksiązki https://www.aristeia.com/books.html są godne polecenia. Ale warto zacząć od googla i hasła "clean code c++".
komentarz 21 stycznia 2021 przez Whiskey_Taster Pasjonat (15,610 p.)
Fajnie, spojrzę na oba zaproponowane tytuły. Wielkie dzięki za poświęcony czas :)
komentarz 21 stycznia 2021 przez Patrycjerz Mędrzec (192,320 p.)
tkz, jeśli dyskusja została zapoczątkowana w sekcji komentarzy, ale później pojawia się odpowiedź na zadane w poście pytanie, to umieść ją w oddzielnej sekcji.

Zaloguj lub zarejestruj się, aby odpowiedzieć na to pytanie.

Podobne pytania

+1 głos
4 odpowiedzi 2,949 wizyt
pytanie zadane 3 lipca 2018 w C i C++ przez Sic Dyskutant (8,510 p.)
0 głosów
1 odpowiedź 152 wizyt
pytanie zadane 24 grudnia 2018 w C i C++ przez Mateuszq28 Nowicjusz (120 p.)
+3 głosów
5 odpowiedzi 1,062 wizyt
pytanie zadane 7 sierpnia 2015 w C i C++ przez kocim Użytkownik (810 p.)

92,579 zapytań

141,429 odpowiedzi

319,657 komentarzy

61,962 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...