Mam problem z kodem spaghetti. Niby już znam język programowania na tyle żeby coś tam małego naszkrobać w konsoli, ale zawsze wychodzi spaghetti.
Skoro tak oceniasz swoją znajomość języka programowania, to mi wydaje się, że spaghetti powinno być nawet trochę oczekiwane. W miarę nauki powinno zniknąć. Ale mogę źle interpretować Twoje słowa.
Czy to już etap na wzorce projektowe?
Hm… Pomijając na chwilę to, co @LukeJL napisał, co rozumiesz przez "etap na wzorce projektowe"?
Jeśli chodzi o pisanie kodu, to już jakiś czas tego nie robiłem. Niemniej może poradzę coś ogólnie…
Jak pisać czytelny kod? Pisząc, miej w głowie, że kod piszesz dla odbiorcy.
Ten, kto ten kod odbiera, ma go zrozumieć. Chodzi przecież o komunikację między Tobą a tym kimś… lub komputerem. I tak: zawsze odbiorcą jesteś Ty (już podczas pisania), prawie zawsze komputer, czasem drugi programista. To moja prywatna klasyfikacja, mogę się mylić. Jestem świadom, że jest tu pewien kontrast z cytatem p. Dolanda Kuntha (https://www.goodreads.com/quotes/6086714-programs-are-meant-to-be-read-by-humans-and-only).
Co oznacza kod czytelny dla Ciebie samego? Nie polegaj tylko na pamięci. Niestandardowych rozwiązań unikaj, a jeśli nie możesz, to notuj je gdzieś, na przykład w komentarzach. Wszelkie standardy bardzo pomagają. Mówią: "y" zawsze w tym kontekście oznacza to i to, "z" to i to, a "y+z" to i to. Nie trzeba się zastanawiać i szukać w głowie, "co mogłem mieć na myśli miesiąc temu, jak to pisałem". Szukaj najbardziej intuicyjnych rozwiązań dla Ciebie samego w dłuższej perspektywie (tj. "łatwo przypominalnych" i "łatwo rozumialnych"). Myślę, że w miarę kodowania będziesz zerkać do standardu coraz mniej, przynajmniej część rzeczy z niego pewnie będziesz mieć w pamięci. Czy będziesz w stanie zrozumieć swoje intencje i decyzje w tym kodzie za rok? To może trudne do przewidzenia, może pomoże zastanowienie się, czy jesteś w stanie teraz zrozumieć swoje decyzje, jak czytasz swój kod sprzed roku (niekoniecznie w tym nowym języku).
Co oznacza kod czytelny dla komputera? Wiedz, co dzieje się z kodem między jego pisaniem a wdrożeniem. Czy jest kompilowany? Interpretowany? Jest jakiś bytecode? Jaki program będzie ostatecznie wykonywał Twój kod? Czy to wszystko wpływa jakoś na wydajność kodu? Czy kompilator połowę Twojego kodu usuwa, a drugą połowę zamienia na "swój"? Generalnie chodzi mi tutaj o to, że w idealnym przypadku komputer zinterpretuje czy skompiluje Twój kod dokładnie tak, jak myślisz, że to zrobi. Tutaj znów napiszę: unikaj niestandardowych rozwiązań i haków. Unikaj opcji kompilatora, których przeznaczenie będziesz znał tylko Ty albo które przydają się w jednym pliku na sto. Stosuj się do standardów, najlepiej tych najszerzej znanych. Znaj oficjalną dokumentację. Czy wspominałem już o unikaniu niestandardowych rozwiązań (nawet tych, które są opisane w oficjalnej dokumentacji)?
Co oznacza kod czytelny dla drugiego programisty? …Tak, standardy i konwencje po raz trzeci, między innymi te związane z formatowaniem kodu. Zauważ, że w wypadku komunikacji człowiek-człowiek standardy nie zawsze muszą być formalnie określone: mam na myśli intuicję. Druga osoba może mieć całkiem inną intuicję niż Ty. Przykładowo nazwa klasy "ABC" może dla niej znaczyć coś innego niż dla Ciebie. Nie chodzi mi o to, żeby polegać lub nie na intuicji, po prostu pamiętaj, że ona tam gdzieś zawsze jest. Inne ważne pojęcia tutaj, moim zdaniem, to kontekst oraz abstrakcje. Kontekst najlepiej by był oczywisty. Przykładowo druga osoba nie powinna musieć się zastanawiać, czy identyfikator "x" w danym pliku ma jakiś związek z identyfikatorem "_x" w innym pliku, ich znaczenie powinno jasno wynikać ze standardów, konwencji, nazw plików, klas i tym podobnych. Poziom abstrakcji staraj się wypośrodkować. Za dużo abstrakcji to wspomniane przez Ciebie overengineering, za mało to właśnie spaghetti (przynajmniej ja bym tak to sklasyfikował). Po co tworzyć dany interfejs, jeśli żadna z przewidywanych klas nie będzie go implementować (overengineering)? Z drugiej strony być może w danym przypadku nie ma sensu robić copy-paste i potem modyfikować tylko niektóre miejsca we wklejonym kodzie (spaghetti). To działanie podatne na przeoczenia, może lepiej wydzielić nową metodę, albo nawet całą klasę.
Te trzy punkty nie są koniecznie rozłączne. Być może porady z jednego da się zastosować w pozostałych. Jak masz pytania, to pisz, może o czymś zapomniałem, a może źle napisałem.
PS W sumie to nie wiem, co masz na myśli przez ową "konsolę".