Jak sie ma młotek, to wszystko wygląda jak gwóźdź - czyli architektura i dobór tools'ów

1

Zgodnie z tym powiedzeniem "jak sie ma młotek, to wszystko wygląda jak gwóźdź" - sami wiecie jak to wygląda w programowaniu.

Zastanawiam się jak radzicie sobie z unikaniem wbijania sruby młotkiem? Jak próbujecie odnaleźć odpowiednie podejście do problemów i wyzwań w pracy?

Pytam bo rozmyślam właśnie nad architektura i użyciem tooli do pewnej apki. Tu sprawa jest taka, że czuje co ta apka ma robić, ale nie wiem jakich tooli użyć, żeby nie narobić sobie kuku, a przy okazji, żeby te toole mi pomogły. Jeśli jest tu jakis architekt lub ktoś kto ma o takich tematach pojęcie to chetnie poczytam

Nie chodzi mi o to żebyście mi doradzili w tym konkretnym przypadku. Raczej o podejście - jeśli jako team dostajecie opis biznesowy aplikacji - jak zabieracie sie do doboru tooli, jezyków itd?

i oczywiście jak podchodzicie do codziennych wyzwań tj wspomniałem na poczatku ;)

0

Ja tam nie mam doświadczenia enterprise, ale wiem że te wzorce, clean code, SOLID, DDT, dużo daje, czasem lepiej toolsów poszukać niż pisać od zera.

Ja teraz będę czytał książkę "Jak to rozwiązać nowoczesna heurystyka", te problemy pewnie rozwiążę co oni będą przedstawiać, ale warto czasem spojrzeć na to jak ktoś inny to interpretuje.
Wiadomo jak się neurony uczą więc warto dużo im inputu zapewnić.

Głównie to dobrze analizować kod czyjś i czytać jakie logiczne motywy on przedstawia, Shalom ostatnio w temacie o stringach fajne logiczne motywy podał, jakie przewiduje, to trochę podobne do gry w szachy i można to sobie w głowie uporządkować, z czego sama logika jest już uporządkowana.

A na końcu to refaktoring, bo później można na coś lepszego wpaść, co umknęło wcześniej i to warto zrobić, tak już mają ludzie.

No i na końcu to jest kompromis, czasem trzeba się poddać, a nie być ciągle nie zdecydowanym, zwykle nie da się w 100% stwierdzić, które narzędzie jest lepsze bo każdy autor swoje dzieło chwali.
A wyjdzie to dopiero po 1 do 3 projektów czy to się nadaje.

1

No i na końcu to jest kompromis

Ano, "every decision is a trade off" :)

Zastanawiam się jak radzicie sobie z unikaniem wbijania sruby młotkiem?

Czasami to najlepszy sposób. Czasem to co się wydawało absurdalne/nieadekwatne, jest najlepszą opcją w danym przypadku.

Tu sprawa jest taka, że czuje co ta apka ma robić, ale nie wiem jakich tooli użyć, żeby nie narobić sobie kuku,

Żeby nie narobić sobie kuku teraz zwykle musisz albo narobić sobie kuku wcześniej, albo widzieć jak inni sobie narobili.
Czyli nauka na błędach albo swoich, albo innych.

Można to przyśpieszyć przez:

  • prototypowanie (zanim robisz coś naprawdę robisz prototyp(albo kilka prototypów) i eksperymentujesz z różnymi podejściami do problemu, różnymi toolami itp.). Dzięki temu kilka dni prototypowania pozwoli ci zebrać wiedzę, którą normalnie zbierałbyś w kilka miesięcy.
  • side-projecty (robisz coś w wolnym czasie i dzięki temu nabywasz więcej doświadczenia, szczególnie robiąc coś od zera samemu albo próbując nowych tooli, których wcześniej nie używałeś)
  • przeglądanie kodu innych ludzi (Github zaprasza), to doskonałe źródło na spojrzenie zarówno na to jak się powinno aplikacje robić, ale również, znacznie częściej, jak się nie powinno pisać (masę kodu na Githubie to kompletny syf - ale to też dobrze, bo uczysz się na błędach innych. pod warunkiem, że umiesz odróżniać syf od dobrego kodu).
  • dlatego warto mieć ogólne spojrzenie krytyczne, refleksyjne, myśleć "co może pójść nie tak" albo spróbować sobie wyobrazić jak w istniejącym kodzie dodałbyś jakąś wymyśloną funkcjonalność (czy obecna architektura ci na to pozwala). Albo np. "w jaki sposób ten zawiły kod można by uprościć?". Myślę, że bardzo mało ludzi ma jakiś bardziej refleksyjny stosunek do kodu. Programują po ileś lat, a dalej popełniają te same błędy, nie umieją wyciągać wniosków.
  • uczenie się od innych, czytanie i słuchanie co inni mówią, w najróżniejszych formach (dużo wiedzy można wyciągnąć choćby z przeglądania issues na Githubie i czytania dyskusji programistów o pewnych konkretnych problemach. Chociaż też trzeba patrzeć krytycznie i czytać między wierszami - dużo problemów wynika nie wcale z tego, że problem jest trudny, tylko, że projekt ma słabą architekturę, w której łatwy problem urasta do miana trudnego).

Pytam bo rozmyślam właśnie nad architektura i użyciem tooli do pewnej apki.

Dobór tooli a architektura to dwie różne rzeczy (nie mówię, że mówisz to to samo, ale wolę to uściślić). Architektura jest ponad toolami i dyktuje to, w jaki sposób te toole mają być używane.

1

U mnie działa: własne-projekty hobby robione w zupełnie innych technologiach i językach. Pisałem w C++ to robiłem hobby w SML. Pisałem w Javie/ Spring to robiłem sobie ćwiczenia Haskell lub Scala/Akka/Akka-HTTP (spray naonczas). Piszę trochę w Scali to robie hobby głownie Haskellu. Pisze w JavaScript i AngularJS to hobby ScalaJS i React.

To mega zmienia - potem nawet durny Spring/Java zaczyna się kodować troche mniej głupio niż zwykle. (bo tak się kończy zwykle kompromis :-)).

0

Przede wszystkim doświadczenie. Jeśli programujesz kupę lat i robisz to ciągle i ciągle tworzysz jakieś projekty i rozwijasz już istniejące, to masz pewne rozeznanie, co się gdzie sprawdziło, a co było kompletną klapą.

Poza tym ciągły własny rozwój. Musisz czytać o nowych technologiach i rozwiązaniach, bo być może widzisz śrubę, próbujesz stworzyć młotkośrubokręt, a już ktoś stworzył przed Tobą najlepszy śrubokręt świata. I daje Ci go za darmo ;)

Książki do wzorców projektowych też się bardzo przydają. Ale to nie są książki w stylu: "Przeczytasz i umiesz". To są książki, do których się wraca. Jak masz określony problem, który "brzmi znajomo", na pewno już widziałeś jakiś wzorzec do tego. Wykorzystaj go. Jeśli potrzebujesz, lekko zmodyfikuj, ale tylko gdy wiesz, co robisz.

Poza tym projektowanie systemu w UML. To nie musi być idealny UML wg specyfikacji (chyba, że polega na nim reszta firmy). On ma Ci pokazać jak wygląda system i gdzie są potencjalne problemy jeszcze zanim zaczniesz pisać kod. Taki diagram będzie się oczywiście zmieniał w trakcie pisania kodu, bo analizując samego UMLa nie wszystko się wychwyci.

Czyli podsumowując:

  • doświadczenie (ciągła praktyka i wyciąganie wniosków)
  • rozwój
  • wzorce projektowe
  • uml

Żeby dobrze zaprojektować aplikację, musisz najpierw zaprojektować kilka aplikacji źle.

3
Juhas napisał(a):
  • wzorce projektowe
  • uml

To dwa to dla mnie idealny przypadek posługiwania sie młotkiem z lat 90tych ubiegłego stulecia i recepta na kupę w systemie.
UML i wzorce to szczyt naiwnej obiektówki, MDA i tym podobnych paskudztw.
Duża część wzorców nie ma już sensu w nowych wersjach Javy, Scali, C#. Łatały dziury, których już nie ma.

0

Diagramy są fajne, ale jeśli chcemy mieć diagramy to warto pamiętać, że UML to tylko jeden mocno zopiniowany standard notacji diagramów (który może się sprawdza jeszcze w językach typu Java, ale mam wrażenie, że stosowanie UML w językach dynamicznych jest trochę bez sensu, bo tam są nieco inne relacje - więc opisywanie np. aplikacji JSowej w notacji UML to trochę jak wbijanie śruby młotkiem).

Z drugiej strony inspiracje można czerpać zewsząd, więc nie ma co demonizować i jak ktoś chce pisać UML, to niech pisze. Ważne, żeby nie uprawiać cargo kultu (czyli: "muszę napisać taką strzałkę, bo tak jest w UML, nawet jeśli to nie ma wiele sensu).

Tak samo wzorce projektowe - z jednej strony robienie z nich cargo kultu i przejaw "profesjonalności" do niczego dobrego nie doprowadzi (poza zrobieniem sobie syfu w projekcie), ale też nie ma co demonizować, bo wzorce projektowe też mogą być fajną inspiracją jak coś można rozwiązać (chociaż często najlepszym wyjściem jest coś, co trochę jednak odbiega od książkowego przykładu, bo książkowe przykłady rzadko dają się przełożyć 1:1, szczególnie jeśli przykład jest w statycznym języku typu Java, C++ czy C#, a piszemy w dynamicznym języku jak JS czy Python, czyli zupełnie inny sposób pisania. Pewne wzorce mogą nawet być nieadekwatne, bo rozwiązują problemy, których w dynamicznych językach w ogóle może nie być).

0

@jarekr000000: tak, ale wiele wzorców nadal ma zastosowanie. Wyobraź sobie że chcesz zwrócić referencje obiektu Download na przykład i na podstawie protokołu URL zwracasz albo HttpDownload albo FtpDownload - fabryka pasuje idealnie :) Strategia na przykład tez jest często używana chociaż już w nieco innej formie (przekazywanie Lambdy), np. Comporator. O tym że Builder bywa bardzo przydatny to chyba nie muszę mówić

0
scibi92 napisał(a):

@jarekr000000: tak, ale wiele wzorców nadal ma zastosowanie. Wyobraź sobie że chcesz zwrócić referencje obiektu Download na przykład i na podstawie protokołu >URL zwracasz albo HttpDownload albo FtpDownload - fabryka pasuje idealnie :) Strategia na przykład tez jest często używana chociaż już w nieco innej formie (przekazywanie Lambdy), np. Comporator. O tym że Builder bywa bardzo przydatny to chyba nie muszę mówić

Fabryka i Strategia to dwa przykladowe konkretyzacji high order function. Tylko po co to tak zawężać. To tak jakby zamiast mówić o "klasach z polami" rozróżniać i pisać oto wzorzec: klasa z dwoma polami. A jest jeszcze wzorzec klasa z trzema polami... (btw. w javaslang jest Tuple2 i Tuple3 :-) ).

A builder to tylko bieda obecnej javy. W jakiejś nowej wersji dorobią się czegoś w stylu scalowe _copy i case class i już nikt nie bedzie wiedział, że buildera używa. (bo poza nielicznymi wyjątkami - to jest główne zastosowanie buildera właśnie w Javie ).

1

Wzorce są wszędzie potrzebne.
A jakie to są wzorce to zależy też od języka. GoF ponoć opisał bardziej uniwersalnie i chwała im za to.
Pewnie nie w każdym języku sensowne (używa ktoś Clojure?).

Nie zapominajmy że jest kilka poziomów wzorców:

  • uzupełniające braki językowe: patterny GoF, idiomy C++
  • enterprise (MVC, Lazy Load, Active Record, DAO, Repository, Session Bean etc)
  • architektura: CQRS, REST, RPC
  • typ oprogramowania: blog, cms, ERP, OS/RTS, driver etc.

Natomiast nie wyobrażam sobie pracy z kodem w którym autorzy sypią lambdami które coś tam robią jak ten nie-FPowy kawałek: https://4programmers.net/Forum/1391189), są bez javadoców i rozpoznawalnej struktury. To byłby jakiś koszmar.
Budując software trzeba budować też abstrakcje (na wielu poziomach), inaczej mamy worek z kodem w którym gdzieś tam można wskoczyć (np. na podstawie stack trace) żeby coś sobie zdebugować.

Pracowałem z takim kodem - kilkanaście tysięcy modułów bez rozpoznawalnych wzorców. Po prostu kilka milionów linii kodu.
Co zrobiłem? Zmieniłem pracę.

0
jarekr000000 napisał(a):
scibi92 napisał(a):

@jarekr000000: tak, ale wiele wzorców nadal ma zastosowanie. Wyobraź sobie że chcesz zwrócić referencje obiektu Download na przykład i na podstawie protokołu >URL zwracasz albo HttpDownload albo FtpDownload - fabryka pasuje idealnie :) Strategia na przykład tez jest często używana chociaż już w nieco innej formie (przekazywanie Lambdy), np. Comporator. O tym że Builder bywa bardzo przydatny to chyba nie muszę mówić

Fabryka i Strategia to dwa przykladowe konkretyzacji high order function.

Co? https://en.wikipedia.org/wiki/Higher-order_function to jest o programowaniu funkcyjnym, a my mówimy o wzorcach w OOP. I jest sens rozrózniania tego,

0
scibi92 napisał(a):

Co? https://en.wikipedia.org/wiki/Higher-order_function to jest o programowaniu funkcyjnym, a my mówimy o wzorcach w OOP. I jest sens rozrózniania tego,

No własnie. To jest przykład walenia obiektowym młotkiem w rzeczy, które akurat funkcyjnie robi się nawet nie wiedząc, że się stosuje jakieś wzorce.
Jak przetrwasz Napolitański akcent to tu jest wykład:

1

@jarekr000000: "Fabryka i Strategia to dwa przykladowe konkretyzacji high order function." - wygląda właśnie trochę jak wbijanie wszystkiego młotkiem.
FP jest modne, więc wszystko co nie FP uznajemy za technologię "z poprzedniej epoki".
A tymczasem nawet dzisiaj są miejsca gdzie programowanie proceduralne się sprawdza.
https://github.com/torvalds/linux

1
vpiotr napisał(a):

@jarekr000000: "Fabryka i Strategia to dwa przykladowe konkretyzacji high order function." - wygląda właśnie trochę jak wbijanie wszystkiego młotkiem.
FP jest modne, więc wszystko co nie FP uznajemy za technologię "z poprzedniej epoki".
A tymczasem nawet dzisiaj są miejsca gdzie programowanie proceduralne się sprawdza.
https://github.com/torvalds/linux

Znam gości, którzy utkwili na Basicu, albo Smalltalku, albo Turbo Pascalu, albo assmeblerze albo Javie 1.4 i im się to doskonale sprawdza. Ba - kase zarabiają i soft nadal sprzedają. To jest doskonały argument.

2

@jarekr000000: to Ty wszędziesz walisz funkcyjnym młotkiem, a prawda jest taka że nie zawsze programowanie funkcyjne jest najlepsze. Ja programuje stylem mieszanym i uważam to za najlepsze

1

@scibi92: mój funkcyjny młotek jest jeszcze za słaby. Na razie walę IMO tak w 1/3 miejsc gdzie by się dało - w całej reszcie BASIC.

1

Ja sie tutaj nie mogę nie zgodzić z @scibi92 bo FP to nie jest panaceum ani silver bullet i jak najbardziej pasuje do tego wątku -> to też taki młotek ktorym ludzie próbują wszystko zrobić :)

Wracajac do tematu to to zwykle robie raczej reaktywnie, tzn uzywam tego co znam i wiem ze sie nadaje i dopiero kiedy trafiam na problem, który wymagałby cudów na kiju, robie rozeznanie w alternatywach.

2
Shalom napisał(a):

Wracajac do tematu to to zwykle robie raczej reaktywnie, tzn uzywam tego co znam i wiem ze sie nadaje i dopiero kiedy trafiam na problem, który wymagałby cudów na kiju, robie rozeznanie w alternatywach.

Zgodnie z tym podejściem powinienem zostać przy programowaniu w C. W C się wszystko da zrobić - jest turing complete. I nie trzeba cudów na kiju.
W BASICU tylko niestety nie mógłbym zostać - bo tam do rekursji niestety potrzebne były cuda na kiju. (A taki był fajny język i miał GOTO).

4

Pozwolę sobie wrócić do oryginalnego pytania. Zacznij od uwolnienia się trochę od myślenia, że musisz dokonać idealnego wyboru. Idealny wybór byłby wtedy, kiedy znałbyś dane narzędzie na wylot i dokładnie znał wszystkie (obecne i przyszłe) wymagania. Jedno i drugie jest niemożliwe do osiągnięcia, co oznacza, że w którymś momencie zawsze się przejedziesz. Wystarczy w zupełności sprawić, że rozwiążesz problem w takiej formie, w jakiej jest to satysfakcjonujące i dla Ciebie, i dla Twojego klienta :).

Jak to zrobić? Przykładowo, możesz sobie narzędzia przeanalizować pod kątem jakichś kryteriów:

  • jakie masz z nimi doświadczenie,
  • czy projekt dopiero wystartował czy jest już w miarę dojrzały,
  • jak duża jest społeczność stojąca za danym projektem,
  • jak duża jest bariera wejścia dla nowej osoby,
  • czy projekt ma jasno opisane założenia.

I potem przyglądasz się im w kontekście tego, co chcesz zrobić:

A. masz zadanie stworzenia niewielkiego projektu, który ma jasno określony czas trwania. Po jego zakończeniu będzie on używany, ale raczej nie będzie już rozwijany zbyt aktywnie.

To jest projekt, w którym osobiście pozwoliłbym sobie na eksperymenty. Jest to miejsce, gdzie można śmiało przetestować jakieś mniej popularne bądź "wschodzące" narzędzia.

B. tworzysz projekt, który będzie rozwijany przez dłuższy czas i będą pojawiały się nowe funkcjonalności. Kod jest dla Ciebie i Twojego zespołu i nikogo innego.

Kluczowe narzędzia takie, jak framework - warto wybrać coś, co choć trochę sprawdziło się w boju, ma dokumentację i jest jakaś społeczność, która danego projektu używa. Projekt będzie istniał przez dłuższy czas, być może przyjdą nowi ludzie. Fajnie byłoby zwiększyć swoje szanse na to, że będą dane narzędzie znać, albo chociaż kojarzyć, aby nie przyuczać ich od zera. Nie przejmowałbym się aż tak mocno barierą wejścia. Jeśli chodzi o Twoje doświadczenie, to sprawa wygląda tak: jak je masz, to super. Jak go nie masz, na bank popełnisz na starcie jakieś błędy projektowe, które później wypadałoby jakoś odkręcić. Możesz zainwestować wcześniej w prototyp, jak masz czas, aby trochę tego doświadczenia zdobyć.

C. tworzysz jakiś framework czy bibliotekę dla innych zespołów. Będziesz miał duże grono technicznych użytkowników.

Tutaj wybór narzędzi musi być przemyślany, gdyż Twoje decyzje mogą wpływać na wiele produktów i kwestie takie, jak społeczność, wsparcie techniczne czy bariera wyjścia odgrywają duże znaczenie. Jeśli ludzie będą mieli problemy i nie będą potrafili ich rozwiązać, przyjdą do Ciebie prosić o pomoc. Jeśli ich będzie dużo, umrzesz pod nawałem pytań. Jeśli robisz framework, lepiej brać też mniejsze biblioteki i komponować z nich gotowe rozwiązanie. Budowanie frameworka na frameworku może się skończyć tym, że bazowy framework zacznie Cię mocno ograniczać. Warto też przyjrzeć się tutaj, z jakich narzędzi korzystają przyszli użytkownicy Twojego projektu i odpowiedzieć sobie na pytanie, jak może wyglądać integracja z nimi.

Niezależnie od Twojego zadania, zawsze trzeba przyjrzeć się założeniom narzędzia. Jeśli stoją one w sprzeczności z tym, co masz zrobić, to automatycznie one odpadają. Cóż, reszta to - jak koledzy wspomnieli - doświadczenie i uczenie się na błędach :).

2

jak dla mnie takim mlotkiem jest event sourcing, przy nowym projekcie pierwsze co robie to mysle jakie eventy bede miec, jakich kolejek uzyje itp
raczej nie pakuje sie we frameworki, celuje w minimalistyczne, stabilne i relatywnie popularne biblioteki (zeby nie byc beta testerem).
przy nowej specyfikacji staram sie napisac dzialajacy prototyp ktory zapewnia podstawowa funkcjonalnosc, klient oczywiscie o tym nie wie ale po tym etapie najczesciej wywalam 90% i robie to porzadnie :)
co do jezyka - do glownych projektow raczej nie mam wyboru bo team jest java/c++, do tych pobocznych to czesto eksperymentuje i przy zadaniach typowo algorytmicznych wybieram haskella albo cos ocamlowego, do automatyzacji python albo groovy + oczywiscie jakies dodatkowe pakiety z sieci w zaleznosci od potrzeb

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