Ocena małego projektu JS (Node.js) + Bash

Odpowiedz Nowy wątek
2019-07-17 21:54
1

Chciałbym poprosić Was o ocenę mojego niedawno rozpoczętego projektu z logiką w JavaScript w Node.js i z interfejsem CLI w Bashu:

https://github.com/silvuss/silvuss-bracket-string-validator

Projekt jest niewielki, jego funkcjonalność jest znikoma (zresztą przeczytajcie README). Niemniej pokładam w nim dwie nadzieje:

  • stanie się kiedyś wizytówką mnie dla samego siebie; co przez to rozumiem? między innymi: będzie dobrze wypozycjonowany, będzie mieć dobrze wymyśloną architekturę, dobrze napisany kod i dokumentację, ukończone wszystkie issues, zrozumiałe commit messages i naprawione wszystkie błędy, jakie można w nim znaleźć (pomijając rzeczy niezależne ode mnie, np. pewne niezbyt trafne konstrukcje języków);
  • będę mógł podpiąć pod niego – jako GUI – interfejs w Angularze; dzięki temu moja nauka podstaw Angulara pójdzie do przodu; obecnie jest jakby zamrożona.

Zależy mi na ocenie całego projektu na GutHubie (nie tylko aplikacji). M.in. chodzi mi o ocenę następujących rzeczy:

  • wydań – czy opisy są zrozumiałe; może dobrze będzie dołączać jakieś pliki, może cały projekt w innym formacie niż obecnie (obecnie jest tylko skompresowany kod źródłowy);
  • issues – szczególnie istotne; czy są dobrze wydzielone, czy nie za dużo / za mało;
  • architektury, w tym obsługi błędów – szczególnie istotne; do poprawy, ale nie mam za bardzo pomysłów, więc chętnie poznam jakiekolwiek sugestie;
  • kodu, w tym komentarze – podział na funkcje, pliki, czytelność, zwięzłość/rozwklekłość, nazwy zmiennych itd.;
  • dokumentacji – szczególnie istotne; np. czy jest czytelna i zrozumiała, czy nie za długa, czy czegoś w niej nie brakuje;
  • czy logika jest w odpowiednim miejscu; może np. trzeba przenieść część z CLI do logiki, a może część z logiki do CLI;
  • czy struktura katalogów w projekcie jest w porządku (jest moja – nie sugerowałem się niczym konkretnym).

Z racji niewielkiego rozmiaru projektu (nie bardzo może być co krytykować :P) najbardziej proszę w powyższych punktach o wskazówki dotyczące wzorców projektowych, które mógłbym użyć, metodologii, bibliotek, frameworków oraz co jeszcze mógłbym dodać jako funkcjonalność do tego projektu. Nowa funkcjonalność powinna być jakoś powiązana ze starą; w tym projekcie nie zależy mi na robieniu aplikacji, która pierze, sprząta i gotuje.

Jak zwykle – wszelkie sugestie są mile widziane. :) W tym – literówki i błędy w dokumentacji czy w komentarzach (tym bardziej, że są po angielsku).

Postaram się tutaj opisywać zmiany w projekcie, dopóki wszystkich sugestii nie rozpatrzę.


Na koniec, korzystając z okazji, chciałbym podziękować dwóm osobom:

  • użytkownikowi @Mr.YaHooo za umieszczenie na naszym forum pierwszej wersji algorytmu sprawdzającego, czy ciąg znaków jest wyrażeniem nawiasowym w tym poście;
  • użytkowniczce @Kate321 za założenie tego wątku; dzięki temu w ogóle poznałem ideę wyrażeń nawiasowych. Trochę szkoda, że już nie wchodzi na forum. @Kate321, jeśli to czytasz, napisz proszę.

UPDATE 19 lipca 2019: Dodałem w projekcie komentarze JSDoc (jak ktoś zna Javę – Wikipedia określa je jako podobne do komentarzy Javadoc). Tutaj wydanie, które to opisuje: https://github.com/silvuss/si[...]validator/releases/tag/v1.1.0


UPDATE 28 lipca 2019: Kolejne, duże, wydanie mojej aplikacji: 1.2.0 (link). Dodałem testy jednostkowe; wykorzystuję przy nich frameworki Mocha oraz Jest. Z innych zmian – nareszcie włączyłem wsparcie dla usługi Travis CI.


edytowany 10x, ostatnio: Silv, 2019-07-28 03:19
Pokaż pozostałe 5 komentarzy
@Silv: Istnieje też coś takiego w psychologii co nazwałbym roboczo "todo trap" (nie pamiętam fachowej nazwy), sam się na tym złapałem kilka razy - czyli sam proces tworzenia sprawia (taski, docs itp.) nam więcej przyjemności niż samo tworzenie (pisanie właściwego kodu) np. oznaczanie tasku jako done daje nam trochę endorfiny i z czasem robimy coraz więcej łatwych tasków żeby je oznaczać jako done - jest o tym trochę więcej w książce "Getting Things Done, czyli sztuka bezstresowej efektywności" (której nie polecam, bo jest nudna) - finalnie projekt rozwija się coraz wolniej. - Markuz 2019-07-18 12:40
@no_solution_found: nazwę silvuss (czyli nazwę pierwotną do Silv, takie coś jakby podawanie argumentów w konsoli w formie --argument zamiast -a ;) ) podaję w przypadku każdego swojego repozytorium. Robię to z dwóch powodów: 1) by było wiadomo, czyje jest repozytorium (np. po sforkowaniu raczej to ktoś zmieni), i nie było nieporozumień; 2) by uspójnić proces rozwoju własnych projektów. - Silv 2019-07-18 16:00
PS. @no_solution_found: własną nazwę nadałem w ogóle w celu uproszczenia pisania skryptu – $1 mówi mi jeszcze mniej. Myślę, że jest to dobra praktyka w przypadku skryptów konsolowych. Dopóki nie przetwarzam argumentów w pętli używając np. shift po pobraniu każdego z nich, to istotne jest zachować poprawną ich kolejność. Dałoby się zmienić nazwy na inne, niepowiązane z kolejnością. Jednak w ten sposób kolejność argumentów byłaby zdefiniowana tylko w miejscu ich pobierania, a to dla mnie chyba trochę za mało. - Silv 2019-07-18 16:05
PS2. @no_solution_found: z Angularem – właśnie napisałem w tym poście, że będę kontynuować. :) Tylko muszę mieć odpowiedni kod, który będę mógł wykorzystać do niego. Taki, żeby coś robił, a z drugiej strony żeby nie zaciemniał mi samego Angulara. Myślę, że ta aplikacja się nada, tylko muszę jakoś ogarnąć kwestie marketingowe na początek (=ważniejsze niż funkcjonalność), np. Travisa CI. - Silv 2019-07-18 16:07
PS3. @Markuz: to może być. Ciekawe. Sam nad podobną kwestią rozmyślałem niedawno. Ja mam cel większy niż ten projekt (ho, ho), ale muszę jakoś podnieść swoją motywację w czasie tworzenia. Postaram się, by rozwój był na tyle dynamiczny, na ile funkcjonalność tej aplikacji pozwoli... no, i moje umiejętności devopsa-marketingowca (których nie posiadam). - Silv 2019-07-18 16:11

Pozostało 580 znaków

2019-07-17 22:58
7

Zgadzam się z tym co piszesz - projekt jest dość mały, ciężko coś sensownie skomentować. Dlatego przyczepię się do drobiazgów :p

To, co zaraz napiszę, grozi flamem pokroju "tabs vs spaces", ale moim zdaniem te wcięcia są za duże. Nie lubię takich mocnych, sam zawsze ustawiam Tab na 2 spacje i tak jest moim zdaniem optymalnie. Większe wcięcia powodują, że po pierwsze kod wydaje się taki rozstrzelony/rozbity, a po drugie przy wielokrotnych zagnieżdżeniach (których oczywiście należy z całą stanowczością unikać ;)) nagle mamy wcięcie na pół ekranu.

Zastanawiam się też, na ile walenie takiej ilości komentarzy ma sens. Gdzieś z tyłu głowy mi dzwoni pewna opinia wyznawana przez bardzo wielu programistów (i jedna z głównych zasad przewijających się cały czas przez "Czysty kod" Martina), czyli że kod powinien sam się dokumentować, komentarze stosuj jedynie w sytuacji, gdzie są konieczne i to w minimalnej ilości.

// JavaScript does not have the stack implemented as such,
// therefore here it is substituted with Array
Wydaje mi się, że kod aplikacji nie jest odpowiednim miejscem do serwowania wykładów odnośnie struktury danego języka.

if (stack.length === 0) {
// We cannot pop from an empty stack,
//  therefore we have to return before
return false; 

Czy naprawdę jest sens takie oczywiste rzeczy wyjaśniać?
Jeśli ktoś nie zrozumie, co robi if (stack.length === 0) {return false} to znaczy, że Twój kod nie jest dla niego przeznaczony, bo koleś podstaw nie ogarnia. No chyba, że piszesz książkę dla początkujących, a ta aplikacja ma być kodem dołączonym do któregoś z rozdziałów ;)


That game of life is hard to play
I'm gonna lose it anyway
The losing card I'll someday lay
So this is all I have to say
edytowany 1x, ostatnio: cerrato, 2019-07-17 23:09

Pozostało 580 znaków

2019-07-17 23:09
3

Zazwyczaj pliki binarne umieszamy w katalogu /bin, jak widzę katalog bin w projekcie to mogę sobie go wylistować i już wiem jakie mogę wykonać polecenia.

Testy zazwyczaj są w katalogu /tests (wtedy nie musimy ich szukać po całym projekcie), dodatkowo nie musimy testować każdego przypadku, z tego co widzę masz ich kilkaset, wystarczyło by 10-20 przypadków testowych (uwzględniając te skrajne). Z założenia testy jednostkowe mają działać szybko, dlatego nie możemy testować wszystkiego. Dobra, widzę, że to testy generowane automatycznie - skoro jesteśmy w stanie je generować automatycznie to może niepotrzebe są te pliki *.json, wystarczyło by je sprawdzać "w locie" podczas uruchamiania testów.

Ogólnie bardzo, bardzo dużo linijek, kodu, dokumentacji i komentarzy a cały projekt mógłby się zamknąć w kilku plikach z kodem js (np. w katalogu src), 3 binach (do odpalenia walidacji, testów i benchmaraków), 1 pliku testowym (w tests) i ew. jednym pliku do benchmarku - często kod który piszemy jest używany przez inne osoby, im więcej zrobimy tego kodu tym więcej czasu zajmie komuś jego przeczytanie.

Ok, po głębszym wczytaniu rozumiem, że chciałeś zrobić porównanie różnych metod na wykonanie tego samego zadania.

Dostajesz od biznesu polecenie:
Panie Silv potrzebujemy dopisać jeszcze jeden algorytm o nazwie "ala-ma-kota" który działa tak - (... opis działania ...).

Pytanie do Ciebie: Ile plików musisz zmienić?

Odpowiedź w idealnym projekcie: 2 lub 3 (albo nawet 1 zakładając, że nie było by dokumentacji)
1 - zawierający algorytm
2 - jakiś config (można go ew. wyelminować jeżeli algorytmy były by w konkretnym katalogu po którym interujemy)
3 - dokumentacja

Odpowiedź w Twoim projekcie: 9
dokumentacje, biny, json i właściwy kod

Jeżeli jednak ten skrypt byłby bardziej zaawansowany, albo nawet byłby to jakiś projekt czy coś który był pisany X lat temu i dostałbym go do utrzymywania - to ta cała otoczka mogła by się przydać. Jednak w tej formie, jest to przerost formy nad treścią.

Widać, że włożyłeś w to dużo serca i czasu - powodzenia w rozwijaniu ;)

edytowany 1x, ostatnio: Markuz, 2019-07-17 23:15
@cerrato: zdążyłeś przeczytać w 5 sekund? ;) - Markuz 2019-07-17 23:10
A czy uważasz, że Twój post jest bezwartościowy? Bo moim zdaniem zasłużył na łapkę :D Przeczytałem pierwsze zdanie oraz popatrzyłem na całość (rozmiar) i uznałem, że się postarałeś, więc dałem łapkę. Potem doczytałem do końca i się utwierdziłem, że to była słuszna decyzja. Jakbym w międzyczasie trafił na bełkot, zawsze łapkę można cofnąć. A poza tym - dość szybko czytam. - cerrato 2019-07-17 23:13
Policzyłem – teraz mam w projekcie łącznie 31 plików kodu i dokumentacji. Ale chyba to nie jest źle, zważywszy, że zakładam, że w 1 pliku powinna być idealnie 1 definicja funkcji/klasy. - Silv 2019-07-17 23:40
@Silv: Sam podział jest jak najbardziej w porządku, ja wyżej kwestionuję tylko pożyteczność niektórych plików - które są a bez nich też projekt dał by radę ;) - Markuz 2019-07-17 23:54

Pozostało 580 znaków

2019-07-17 23:30
2
cerrato napisał(a):

Zgadzam się z tym co piszesz - projekt jest dość mały, ciężko coś sensownie skomentować. Dlatego przyczepię się do drobiazgów :p

I o to chodzi!

To, co zaraz napiszę, grozi flamem pokroju "tabs vs spaces", ale moim zdaniem te wcięcia są za duże. Nie lubię takich mocnych, sam zawsze ustawiam Tab na 2 spacje i tak jest moim zdaniem optymalnie. Większe wcięcia powodują, że po pierwsze kod wydaje się taki rozstrzelony/rozbity, a po drugie przy wielokrotnych zagnieżdżeniach (których oczywiście należy z całą stanowczością unikać ;)) nagle mamy wcięcie na pół ekranu.

Ja mam odwrotnie niż Ty – nie lubię zmian i dlatego staram się nie zmieniać wartości domyślnych w edytorach. A że Visual Studio Code ma takie wcięcia domyślne dla kodu JS, kodu Basha oraz dla JSON-a, to i takie są.

Zastanawiam się też, na ile walenie takiej ilości komentarzy ma sens. Gdzieś z tyłu głowy mi dzwoni pewna opinia wyznawana przez bardzo wielu programistów (i jedna z głównych zasad przewijających się cały czas przez "Czysty kod" Martina), czyli że kod powinien sam się dokumentować, komentarze stosuj jedynie w sytuacji, gdzie są konieczne i to w minimalnej ilości.

That may be true. Fajnie, że dałeś odniesienie do Martina (kiedy ja tę książkę przeczytam?). Zobaczę, co się da z tym zrobić.

// JavaScript does not have the stack implemented as such,
// therefore here it is substituted with Array
Wydaje mi się, że kod aplikacji nie jest odpowiednim miejscem do serwowania wykładów odnośnie struktury danego języka.

Sam nie wiem, dlaczego, ale obecnie wydaje mi się to potrzebne.

if (stack.length === 0) {
// We cannot pop from an empty stack,
//  therefore we have to return before
return false; 

Czy naprawdę jest sens takie oczywiste rzeczy wyjaśniać?
Jeśli ktoś nie zrozumie, co robi if (stack.length === 0) {return false} to znaczy, że Twój kod nie jest dla niego przeznaczony, bo koleś podstaw nie ogarnia. No chyba, że piszesz książkę dla początkujących, a ta aplikacja ma być kodem dołączonym do któregoś z rozdziałów ;)

Nie planowałem tego kodu dla początkujących w JS (ale nie obraziłbym się, gdyby ktoś kiedyś ;) ). Niemniej akurat w tym wypadku uważam, że jest sens – jest to algorytm, który nie był dla mnie na początku oczywisty. I myślę, że dla niewielu osób będzie – w końcu tak proste i nieużyteczne algorytmy czyta się raz i zapomina. Więc dobrze, by był jasny w każdym calu.


Markuz napisał(a):

Zazwyczaj pliki binarne umieszamy w katalogu /bin, jak widzę katalog bin w projekcie to mogę sobie go wylistować i już wiem jakie mogę wykonać polecenia.

OK, to w zasadzie już wiem. Tylko widzisz – problem jest taki, że na razie nie wiem, jak taki plik binarny utworzyć i co powinien zawierać w przypadku tej aplikacji.

Testy zazwyczaj są w katalogu /tests (wtedy nie musimy ich szukać po całym projekcie), dodatkowo nie musimy testować każdego przypadku, z tego co widzę masz ich kilkaset, wystarczyło by 10-20 przypadków testowych (uwzględniając te skrajne). Z założenia testy jednostkowe mają działać szybko, dlatego nie możemy testować wszystkiego. Dobra, widzę, że to testy generowane automatycznie - skoro jesteśmy w stanie je generować automatycznie to może niepotrzebe są te pliki *.json, wystarczyło by je sprawdzać "w locie" podczas uruchamiania testów.

Testy były generowanie, jak napisałem, semi-automatically (chyba że mówisz o danych do benchmarku?) – przypadki były generowane automatycznie, ale te przypadki, które są poprawne, musiałem sam wyszukiwać i opisywać jako true. :) Ogólnie wolę czegoś takiego nie robić, bo człowiek jest omylny... Ale inaczej się nie dało.

Ogólnie bardzo, bardzo dużo linijek, kodu, dokumentacji i komentarzy a cały projekt mógłby się zamknąć w kilku plikach z kodem js (np. w katalogu src), 3 binach (do odpalenia walidacji, testów i benchmaraków), 1 pliku testowym (w tests) i ew. jednym pliku do benchmarku - często kod który piszemy jest używany przez inne osoby, im więcej zrobimy tego kodu tym więcej czasu zajmie komuś jego przeczytanie.

Do przemyślenia, bo poruszasz wiele spraw. Część z nich mam już w głowie.

Ok, po głębszym wczytaniu rozumiem, że chciałeś zrobić porównanie różnych metod na wykonanie tego samego zadania.

No, wydaje się to dziwne na początku. :P

Dostajesz od biznesu polecenie:
Panie Silv potrzebujemy dopisać jeszcze jeden algorytm o nazwie "ala-ma-kota" który działa tak - (... opis działania ...).

Pytanie do Ciebie: Ile plików musisz zmienić?

Odpowiedź w idealnym projekcie: 2 lub 3 (albo nawet 1 zakładając, że nie było by dokumentacji)
1 - zawierający algorytm
2 - jakiś config (można go ew. wyelminować jeżeli algorytmy były by w konkretnym katalogu po którym interujemy)
3 - dokumentacja

Odpowiedź w Twoim projekcie: 9
dokumentacje, biny, json i właściwy kod

Jeżeli jednak ten skrypt byłby bardziej zaawansowany, albo nawet byłby to jakiś projekt czy coś który był pisany X lat temu i dostałbym go do utrzymywania - to ta cała otoczka mogła by się przydać. Jednak w tej formie, jest to przerost formy nad treścią.

To jest ważna kwestia do rozważenia. Dzięki!

Widać, że włożyłeś w to dużo serca i czasu - powodzenia w rozwijaniu ;)

Dzięki. :)


Przez plik binarny miałem na myśli plik bashowy jak np. ten - https://github.com/silvuss/si[...]/blob/master/app/cli/valbrstr - chociaż on nie jest binarny, to mimo wszystko może trafić do katalogu bin jako, że możemy go wykonywać z lini poleceń ;) - Markuz 2019-07-17 23:36
Trochę to dziwne, ale skoro tak mówisz, to poczytam, może rzeczywiście taki lekki chaos przyczyni się do uporządkowania aplikacji. - Silv 2019-07-17 23:37
Dzięki! - Silv 2019-07-18 00:12

Pozostało 580 znaków

2019-07-18 10:30
2

Dziękujesz dwóm osobom za ich wątki na tym forum a do Sources w README tych linków już nie dodałeś :)

Pozostało 580 znaków

2019-07-18 16:23
0

@baant: rzecz wygląda tak: jeden ze wspomnianych linków już jest w Credits. W Sources podaję odniesienia tylko do takich źródeł, które w mojej ocenie przekazują odpowiednio dużą wiedzę na temat dziedzin i technologii, które wykorzystuje projekt. Drugi ze wspomnianych przez Ciebie linków mógłbym też dać do Credits. I chyba to zrobię.


Pozostało 580 znaków

2019-07-18 16:24
0
if (!bracketString) {
        // The argument is a falsy value
        //  (which includes being an empty string)
        // See https://developer.mozilla.org/en-US/docs/Glossary/Falsy
        return false;
    }

    if (!bracketString.substring) {
        // The argument is not a string
        return false;
    }

IMO tego typu komentarze są zdecydowanie zbędne i tylko utrudniają czytanie całości


Spring? Ja tam wole mieć kontrole nad kodem ᕙ(ꔢ)ᕗ
Haste - mała biblioteka do testów z czasem.

Pozostało 580 znaków

2019-07-18 16:37
0

@danek: pierwszy rzeczywiście można wyrzucić. Drugiego nie, bo sprawdzanie istnienia metody substring jest moim zdaniem wystarczająco niestandardowe, by nie być jasnym bez takiego komentarza.


Pokaż pozostałe 23 komentarze
przydałby się jakiś nowy język, który byłby bardzo podobny do JavaScriptu, ale bez WTFów, z bardziej przemyślaną biblioteką standardową, z bardziej przemyślaną składnią i z bardziej przemyślaną obiektówką czy ogólnie systemem typów. Czyli takie jakby "JavaScript made right" - LukeJL 2019-07-22 18:36
no i ze wsparciem immutowalności, żeby dało się łatwo programować funkcyjnie. - LukeJL 2019-07-22 18:36
typescript ? - filemonczyk 2019-07-22 18:36
@filemonczyk no właśnie nie, bo TS bierze składnie z JSa, czyli jest to tak samo poronione i niespójne. - LukeJL 2019-07-22 18:37
chociaż w przyszłości może język nie będzie mieć znaczenia, bo WebAssembly - każdy będzie pisać w swoim ulubionym języku (tylko, żeby się to udało to te języki muszą współpracować ze sobą). - LukeJL 2019-07-22 18:43

Pozostało 580 znaków

2019-07-19 18:06
0

Hej, dodałem w aplikacji komentarze JSDoc (jak ktoś zna Javę – Wikipedia określa je jako podobne do komentarzy Javadoc). Tutaj wydanie, które to opisuje: https://github.com/silvuss/si[...]validator/releases/tag/v1.1.0

JSDoc wcześniej prawie nie znałem. Zapraszam do oceny, czy mają sens. :)


edytowany 2x, ostatnio: Silv, 2019-07-19 18:07

Pozostało 580 znaków

2019-07-19 18:41
2

Co to za aplikacja której nie możesz odpalić. Jak się boisz, że coś skopałeś to wpakuj to w Dockera. Odpaliłem, działa ok, możesz dodać:

Dockerfile

FROM node:10.16.0
WORKDIR /usr/src/app
COPY . .

Odpalanie:

W katalogu głównym aplikacji gdzie znajduje się Dockerfile uruchom jednorazowo:

`docker build -t bracket-validator .`

Aby odpalić apkę wpisz:

`docker run -it bracket-validator /bin/bash`
edytowany 3x, ostatnio: Maciej Cąderek, 2019-07-19 18:43

Pozostało 580 znaków

2019-07-19 18:47
0

@Maciej Cąderek: nie znam Dockera, ale domyślam się, że to coś do wirtualizacji pojedynczych aplikacji. Poczytam. Może przydać się w przyszłości. Dzięki!

Co do uruchomienia aplikacji jako takiego – nie rozumiem, dlaczego piszesz, że nie możesz odpalić, skoro potem piszesz, że możesz?


Co Dockera, najlepszy imo wstęp znajdziesz tutaj: https://docker-curriculum.com/ - Maciej Cąderek 2019-07-19 19:15
O, dzięki. Zobaczę, aczkolwiek najpierw jak zwykle – Wikipedia. - Silv 2019-07-19 19:15

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0