Anonim1 napisał(a)
To jak bedziesz nazywal swoje zmienne/funkcje/parametry/klasy itd jest tylko konwencja i dopoki bedziesz sie trzymal zawsze jednej ustalonej przez siebie konwencji to bedzie dobrze.
@Bumcykowy:
Nie jest prawdą, że wystarczy wymyślić/wybrać sobie dowolną konwencję i się jej trzymać i już będzie dobrze (pod względem formatowania).
Wybrana konwencja musi jeszcze być sensowna! Formatowanie powinno podkreślać strukturę kodu.
W obecnym kształcie kodu można debatować nad sensem wcinania kolejnych linii z parametrami konstruktora:
c napisał(a)
Przedmiot(string nazwa_, string rodzaj_, int atakMagiczny_,
int atakFizyczny_, int obronaMagiczna_, int obronaFizyczna_,
int minPoziom_, int cenaKupna_);
Dlaczego linia z ostatnimi dwoma parametrami jest bardziej wcięta niż linia poprzednia? Czemu każda nowa linia instrukcji ma być bardziej wcięta? Sugeruje to jakieś zagnieżdżenie, tak jak np. w przypadku użycia zagnieżdżonych operatorów trójargumentowych (? :
). Tutaj jednak zagnieżdżenia nie ma, więc coraz większe wcięcie dla kolejnych linii jest mylące. Przy czym jakieś wcięcie drugiej linii argumentów (i takie samo wcięcie kolejnych linii) jest logiczne: lista argumentów jest częścią deklaracji funkcji, mamy więc hierarchię: coś jest nadrzędne, coś podrzędne. Ale dwa ostatnie argumenty nie są podrzędne w stosunkud o poprzednich, więc nie ma co ich wcinać.
Tak duża liczba argumentów jest "złym zapachem" w kodzie. Jest bardzo złym zapachem, gdy mowa o zwykłych funkcjach. Konstruktory... niektórzy uznają za pewien wyjątek i przymykają oko na dużą liczbę argumentów. W przypadku normalnej funkcji, nawet dwa argumenty to już wiele. Stanowią utrudnienie jeśli nie przy pisaniu kodu (bo IDE podpowiada), to przy czytaniu. Np. w JUnitowym assertEquals(foo, bar)
który argument jest expected, a który actual? W innych frameworkach testowych, w stylu BDD, możemy mieć zamiast tego expect(foo).toEqual(bar)
, co jest czytelniejsze i się nie myli. Wystarczy chwilę pomyśleć by zjarzyć, co jest czym. Kolejności argumentów w assertEquals()
wydedukować się nie da.
Użycie wspomnianego wyżej wzorca Budowniczy jest OK. W ogóle, jeśli masz tyle statystyk, to pewnie wartoby je inicjalizować np. z jakiegoś pliku. Warto jednak czynić takie modyfikacje, mając świadomość zarówno plusów, jak i minusów. Np. jeśli statystyki wczytywalibyśmy z pliku czy z jakiejś mapy (przy czym wtedy moglibyśmy całkowicie pozbyć się publicznego konstruktora z wieloma parametrami), stracilibyśmy część ochrony podczas kompilacji. Co, jeśli w pliku konfiguracyjnym lub mapie brakowałoby jakiegoś parametru? Albo co jeśli, korzystając z budowniczego, zapomnielibyśmy wywołaćatakFizyczny(10)
? Kompilator tego już nie wykryje. Musielibyśmy porządnie zadbać o obsługę błędów.
Zresztą, długą listę parametrów konstruktora mimo wszystko też można oszukać. Jeśli przez przypadek, podczas inicjalizacji, zamienisz miejscami atakFizyczny
i obronęMagiczną
, a więc dwie zupełnie inne rzeczy, to kompilator Cię nawet nie ostrzeże, bo oba parametry są dla niego intami i tyle.