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

Dobre praktyki w programowaniu - C++

Aruba Cloud VPS - 50% taniej przez 3 miesiące!
–1 głos
283 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,020 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,020 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,020 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 3,161 wizyt
pytanie zadane 3 lipca 2018 w C i C++ przez Sic Dyskutant (8,510 p.)
0 głosów
1 odpowiedź 183 wizyt
pytanie zadane 24 grudnia 2018 w C i C++ przez Mateuszq28 Nowicjusz (120 p.)
+3 głosów
5 odpowiedzi 1,231 wizyt
pytanie zadane 7 sierpnia 2015 w C i C++ przez kocim Użytkownik (810 p.)

93,176 zapytań

142,185 odpowiedzi

321,980 komentarzy

62,506 pasjonatów

Advent of Code 2024

Top 15 użytkowników

  1. 1637p. - dia-Chann
  2. 1614p. - Łukasz Piwowar
  3. 1599p. - CC PL
  4. 1597p. - Łukasz Eckert
  5. 1537p. - Łukasz Siedlecki
  6. 1531p. - rucin93
  7. 1356p. - ssynowiec
  8. 1351p. - Tomasz Bielak
  9. 1328p. - Michal Drewniak
  10. 1288p. - rafalszastok
  11. 1273p. - Adrian Wieprzkowicz
  12. 1232p. - Mikbac
  13. 1169p. - Grzegorz Aleksander Klementowski
  14. 1155p. - Piotr Aleksandrowicz
  15. 1149p. - Michał Telesz
Szczegóły i pełne wyniki

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

Wprowadzenie do ITsec, tom 1 Wprowadzenie do ITsec, tom 2

Można już zamawiać dwa tomy książek o ITsec pt. "Wprowadzenie do bezpieczeństwa IT" - mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy aż 15% zniżki! Dziękujemy ekipie Sekuraka za fajny rabat dla naszej Społeczności!

...