(Nie)projektowanie i rozwój oprogramowania a YAGNI

(Nie)projektowanie i rozwój oprogramowania a YAGNI
superdurszlak
  • Rejestracja:prawie 7 lat
  • Ostatnio:4 dni
  • Lokalizacja:Kraków
  • Postów:1999
0

Uprzedzając pytania i pouczenia - nie chodzi mi o funkcjonalność tworzonego systemu i rzeźbienie ficzerów na wyrost, lecz o sposób, w jaki (nie)powstaje jego design, architektura etc ;)

Pytam dlatego, że mam (nie pierwszy raz zresztą) déjà vu, gdy patrzę na rzeczy, które klepię lub inni klepią i już sam nie wiem, czy to objawy syndromu niemieckiego architekta lub innego strasznego choróbska, czy co.

Piszę o déjà vu dlatego, że przeważnie wygląda to w miarę podobnie i ma podobne etapy - z moim udziałem lub bez, lub tylko częściowym i w niektórych etapach, nieważne:

  • zaczyna się projekt
  • jak się go zaczyna robić, to realizacja przebiega w ogólnie akceptowanym przez zespół planie minimum, to może oznacza na przykład "encja na twarz i pchasz" lub klasyczna trójwarstwowa lazania z frameworkiem X z przodu i bazą Y z tyłu w backendzie, ale tak naprawdę w grę wchodzą dowolne drogi na skróty, które krótkoterminowo nie spowodują większych reperkusji
  • z początku z wybranym planem minimum da się jakoś żyć, w projekcie nie ma dużo skomplikowanych zależności więc jeszcze się to nie mści - nie ma bodźca by odejść od planu minimum, bo YAGNI, nie twórzmy architektury na wyrost, jest dobrze jak jest, jakoś się żyje, nie wiadomo co będzie potrzebne więc po co wymyślać, jesteśmy agile a nie waterfall
  • kula błota powoli rośnie, na tyle wolno że działa efekt gotowanej żaby
  • przy odrobinie szczęścia projekt umiera lub przechodzi w utrzymanie zanim kula błota przekroczy masę krytyczną
  • jak szczęścia zabraknie, to drogi na skróty zaczynają w końcu kopać w d**ę przy wprowadzaniu kolejnych zmian, strach to ruszać, no i tak się żyje z legacy czasu rzeczywistego

Co więcej, widzę to nawet wtedy, gdy nie gonią terminy i nie trzeba dowozić na wczoraj. Nie ukrywam, że sam też długo kierowałem się takim myśleniem, radośnie produkowałem legacy na bieżąco i dawałem złapać na gotowaną żabę :D Niemniej jednak coraz bardziej mi ten stan rzeczy - i jego (postrzegana przeze mnie) wszechobecność - przeszkadza. No, ale jako cienki bolek z mlekiem pod nosem to sobie mogę.. ;)

Jak wy do tego podchodzicie? Trzymacie się do końca tego planu minimum, umiecie powiedzieć "sprawdzam" i popchnąć projekt w kierunku, który uważacie za słuszny, zanim dotychczasowy będzie zbyt upierdliwy albo nawet później? A może od samego początku nie akceptujecie pewnych dróg na skróty - jeśli tak, to gdzie wyznaczacie granicę?

@Charles_Ray @Afish @Shalom @hauleth @kq @krwq @jarekr000000 jeśli macie czas i chęci, podzielcie się swoją perspektywą ;)


edytowany 2x, ostatnio: superdurszlak
UR
  • Rejestracja:prawie 5 lat
  • Ostatnio:prawie 3 lata
  • Postów:360
1

Ja często spotykam się z anemicznymi modelami całkowicie powiązanymi z ORMem, jednym DTOsem do wszyskiego.

No i każda próba przeforsowania czegoś nowego spala się na panewce, bo albo traci się czas na powtórną analizę zadania, bo osoba za to odpowiedzialna jak zwykle to skopała, albo deadline jest na wczoraj, albo robisz projekt z osobą, która nie ma pojęcia i koniec końców robicie po linii najmniejszego oporu, albo pseudoarchitekt/pm/manager/właściciel wymusza użycie istniejących bibliotek w innych projektach, co już samo w sobie powoduje, że ciężko z gówna wyrzeźbić.

Bywa i tak, że człowiek kombinuje jak koń pod górkę, chociażby z optymalizacją sql, bo firma januszex sa ma bazę danych na azure, bez żadnych indeksów, bo za większą przestrzeń dyskową trzeba więcej zapłacić, elasticsearch - nie, cache - nie, cokolwiek - nie.
No i co człowiek ma zrobić, jak z wyszukiwarki do bazy leci LIKE po 10 kolumnach.

No i kończy się to tak, że człowiek bierze dłuto i rzeźbi, traci chęci i nadzieje, szuka nowej pracy, łapie haczyk HRu, po czym otrzymuje jeszcze większe dłuto do ręki :)

edytowany 1x, ostatnio: urke
Charles_Ray
Dziwne z tym Januszexem, bo wystarczy zrobić test i pokazać dane, że to pier***lnie. Żadna firma tego nie chce, bo to dla niej strata kasy w przypadku wadliwego produktu.
UR
Gorzej jak szef januszexu jest zarówno głównym programistą, dobrze o tym wie i nic z tym nie zrobi, bo nie dopłaci kilku tysięcy miesięcznie za serwer na bazę z większą przestrzenią dyskową, a do innych rozwiązań podchodzi sceptycznie, bo ich nie zna :)
Charles_Ray
  • Rejestracja:prawie 17 lat
  • Ostatnio:około 16 godzin
  • Postów:1873
8

Kuba Pilimon fajnie powiedział, że zaczęliśmy traktować podejście „no big design upfront” jako „no design at all”.

Dużo zależy od kontekstu - jak skomplikowana jest domena, czy robimy MVP, czy osadzamy się w istniejącej architekturze, jakich mamy ludzi, ile czasu, jakie normy musimy spełniać itd. (tzw. drivery architektoniczne).

Zwykle jednak występuje po prostu brak strategicznego myślenia, a jedynie prześciganie się na buzzwordy i wzorce taktyczne, które niewiele wnoszą. Łatwiej dodać do projektu takiego Vavra czy Reactora i wpisać go sobie do LinkedIna niż zastanowić się nad ograniczeniami, wyzwaniami domenowym i kierunkiem rozwoju softu.

Dobry soft wymaga planu + nie całą aplikację trzeba stawiać na jedną modłę - można podzielić na moduły i każdy znich zrobić w innej architekturze tak, żeby tez nie wszystko kodować w portach adapterach czy mikroserwisach - to patologia w drugą stronę.

Jeśli chodzi o drogę na skróty - jak najbardziej! Tylko trzeba wiedzieć, gdzie świadomie przyciąć, gdzie można skipnąć jakiś wzorzec czy warstwę. Ja to nazywam świadomym zarządzaniem jakością i długiem technicznym. Naprawdę czasem mogę ogarnąć cały moduł/MVP za pomocą Springa i JPA w tydzień, zamiast rzeźbić jakieś pure functional state-of-the-art cuda wianki. Jakaś cześć kodu wykonuje się 50ms, a mogłaby po optymalizacji 10ms? Może na danym etapie rozwoju można z tym żyć.

Jak do tego podejść? Doświadczenie + jest sporo wiedzy na ten temat. Planowanie rozwoju aplikacji to robota dla bardziej doświadczonych członków zespołu, którzy chcą się rozwijać w kierunku architektów. Do tego przydaje się otwartość na ludzi z biznesu, o czym pisałem na mikroblogu.


”Engineering is easy. People are hard.” Bill Coughran
edytowany 9x, ostatnio: Charles_Ray
Zobacz pozostałe 5 komentarzy
superdurszlak
@scibi92: co mi po vavr, jak w zależnościach będzie jeden wielki precel, albo ktoś będzie radośnie mapował nie wiem, DTO do entitki do innego DTO i dopiero przez drugą entitkę do message'a który dopiero pójdzie, bo tak było komuś wygodniej nahakować. No i oczywiście testów brak, bo spowalniają development :]
S9
@Charles_Ray tak, ciekawe tylko że ciągle piszesz o Vavrze jako buzzwordzie, a o Springu już tak nie napiszesz chociaż to o wiele większy buzzword, nie mówiąc już o JPA które jest wszędzie wpychane :D
superdurszlak
ale mainstream to nie to samo co buzzword
S9
A czy buzzword nie może być mainstreamowy?
superdurszlak
jak dla mnie tak se, im bardziej coś jest mainstreamowe tym bardziej powszednieje i traci swój efekt "wow", a na tym "wow" polegają buzzwordy ;)
AF
  • Rejestracja:prawie 18 lat
  • Ostatnio:11 dni
7

Gdy ludzie uczą się czegoś nowego, to rozumieją, że za pierwszym razem nie wyjdzie poprawnie, ale jak piszą aplikację, to jakoś zawsze się łudzą, że potrafią zrobić tak, żeby nie trzeba było poprawiać. No ale rzeczywistość świetnie pokazuje, że o ile nie piszesz tej samej aplikacji piąty raz, to zawsze się w coś wkopiesz. Trzeba zaakceptować fakt, że aplikacja nie jest wyryta w kamieniu i trzeba będzie część (w skrajnych przypadkach całość) pracy wyrzucić i zrobić od nowa, mając dodatkowe doświadczenie i wiedzę.

Jeżeli nie zgadzasz się, aby jutro wyrzucić kod napisany dzisiaj, to w końcu utkniesz w legacy. Dopiero gdy zaakceptujesz to ryzyko, wtedy będziesz mógł ze spokojem rozwijać aplikację, bo nie będzie tego strachu/smutku/rozczarowania, że tyle czasu spędziłeś nad elementem X, a teraz trzeba go wywalić i zacząć od nowa.

Większość ludzi i firm nie lubi tego podejścia i szukają jakichś sposobów, aby za pierwszym razem zrobić idealne rozwiązanie. A potem jednak okazuje się, że (według statystyk) wymagania zmieniają się o 30%, a budżet jest przekroczony dwukrotnie.

Jak już przyjmiemy podejście, w którym nie boimy się wyrzucenia kodu (modułu, komponentu, serwisu itp.), to trzeba zacząć pisać aplikacje tak, aby usuwanie było jak najprostsze. Przede wszystkim trzeba mieć sensowny model, bo błąd w tym obszarze jest praktycznie nieodwracalny. Potem wprowadzamy małe konteksty (jak z DDD) i pilnujemy ich niezależności. Potem dbamy o kontrakty między kontekstami, tu przydaje się bardzo doświadczony architekt, który już takie rzeczy klepał i wie, gdzie popełnił błędy. A potem już jest o wiele prościej, bo gdy jakiś moduł X będzie skopany, to się go przepisze i kluczowe jest, żeby przepisanie trwało miesiąc zamiast roku.

Jeżeli zaś nie chcemy takiego podejścia i ze wszystkich sił walczymy o trzymanie tego, co już zostało napisane, to potrzebny jest dobry architekt (który już popełnił błędy) i zamrożone wymagania. Jeżeli tego nie ma, to i tak skończymy z legacy, kwestia czasu.

Gwiazdka 1: Piszę to z perspektywy systemu rozproszonego, pisanego z ideą mikroserwisów i rozwijanego przez 5+ lat. W innych sytuacjach opisane wyżej podejście może nie być dobre.

Gwiazdka 2: Okej, a jak w takim razie zrobić dobry model i dobre kontrakty? Tu są 3 elementy: 1) doświadczenie domenowe - rzeczywistość zaskakuje, drzewa genealogiczne nie są drzewami, pesele nie są liczbami i mają kolizje, a adresy nie są postaci Ulica Numer. Takich rzeczy raczej się nie przewidzi, trzeba się odpowiednio naciąć 2) doświadczenie innych - dobrze jest pogadać z innymi architektami, dzielić się doświadczeniem, chodzić na konferencje itp., to naprawdę pomaga w zrozumieniu, co w praktyce się sypie. Dobrze jest mieć jakiegoś konsultanta, który niekoniecznie pisał 100 systemów, ale widział ich problemy. 3) jakieś typowe "best practices", czyli jak wersjonować, jak opakować identyfikatory w value objecty czy coś, jak zrobić przestrzenie nazw, jak zrobić haki na przyszłość (jakaś hashmapa na nieprzewidziane pola itp.), to jest opisane w książkach/konferencjach, trzeba się po prostu wyedukować.

edytowany 2x, ostatnio: Afish
WeiXiao
(jakaś hashmapa na nieprzewidziane pola itp.) ostatnio mnie tak naszło aby jakieś corner caseowy flagi zamienić na kolekcje "atrybutów" i w sumie brzmi to tak jak piszesz "nieprzewidziane pola" (lub hacki :D)
AF
No prędzej czy później zawsze taka hashmapa się przyda. Do tego powinna być druga z metadanymi do debugowania, które będą odpalane tylko w debugu. Poza tym kwestia kompatybilności wstecznej, w przód itp, każdy prędzej czy później trafia na takie problemy, ale to jest coś, przez co ludzie już przeszli i można się tego nauczyć przed popełnieniem błędów.
LukeJL
  • Rejestracja:około 11 lat
  • Ostatnio:minuta
  • Postów:8398
2

kula błota powoli rośnie, na tyle wolno że działa efekt gotowanej żaby

Tutaj. Na tym etapie powinien być wcielany refaktoring i zasada skauta. Ale do tego trzeba teamu, który widzi potrzebę refaktoru (bo wiele osób nie ma poczucia stylu i uważa, że dobrze jest jak jest, byle działało) i który ma tyle dyscypliny, żeby go wprowadzać (tutaj zarządzanie jeszcze musi nie przeszkadzać, bo jak PM będzie naciskać na "wincyj ficzerów", a próby refaktoringu/pisania testów/czegokolwiek będą hejtowane - to raczej się nic nie zrobi).

Czyli pisanie byle jak, byle do przodu jest okej na krótką metę, ale trzeba to potem spłacać, ten dług techniczny.

YAGNI, nie twórzmy architektury na wyrost

Często nie da się od razu zaprojektować aplikacji, jeśli się wcześniej nie robiło podobnej (chyba, że apka jest trywialna), więc z tą architekturą to niby okej, że nie na samym początku. Pierwsze etapy pracy nad nowym projektem lepiej potraktować jako zwykłe prototypowanie i zbieranie wymagań. Bo tak to wygląda w końcu. Coś robisz, nie wiesz najpierw co, musisz czytać wymagania, myślisz jak zrobić, coś robisz, konsultujesz z innymi, w końcu ileś tasków później zbieracie projekt do kupy, bo już coś działa, już coś się pokazuje.

Tylko, że architektonicznie to zwykle kupa (w zależności od kultury teamu - albo spaghetti kod pisany na kolanie, albo coś na maksa przeinżynierowanego - i z dwojga złego wolę to pierwsze - łatwiej jest nadać kształt czemuś, co kształtu nie ma, niż rozmontowywać kawałek po kawałku jakieś chore przeinżynierowane abstrakcje). I na tym etapie można się pobawić w refaktoring, wydzielanie sensownych abstrakcji, przepisanie kawałka kodu od zera itp.


danek
  • Rejestracja:ponad 10 lat
  • Ostatnio:6 miesięcy
  • Lokalizacja:Poznań
  • Postów:797
3

Wydaje mi się, że dużo pomaga modułowość i możliwość łatwego wywalenia całego modułu i napisania od 0, Łatwiej jest zmieniać takie pojedyncze małe rzeczy niż przepisywać pół systemu. Łatwiej też to potem testować


Spring? Ja tam wole mieć kontrole nad kodem ᕙ(ꔢ)ᕗ
Haste - mała biblioteka do testów z czasem.
loza_wykletych
loza_wykletych
Modułowość to oznaka że jednak jakaś architektura jednak w projekcie istnieje. Chociaż moduł może mieć interfejsy do sieci, storage i logiki biznesowej i pierdylion zależności :D
Miang
  • Rejestracja:prawie 7 lat
  • Ostatnio:około 2 godziny
  • Postów:1659
1

Ja wyznaczam granicę przy próbie zrobienia tego co jest w tytule - czyli rozpoczęcia pracy bez zrobienia projektu przynajmniej w bardzo ogólnym sensie. Ciekawe że jak trzeba przygotować wycenę dla zewnętrznego klienta to szefostwo nagle widzi sens takiego projektu.....


dzisiaj programiści uwielbiają przepisywać kod z jednego języka do drugiego, tylko po to by z projektem nadal stać w miejscu ale na nowej technologii
edytowany 1x, ostatnio: Miang
jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 3 godziny
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4706
3

Ogólnie to akceptuje drogi na skróty, ale im większy i sensowniejszy projekt tym mniej.
Warstwy, projekty i inne cuda - olewam.
Za to testy, nawet w małych projektach, muszą być sensowne.

Co do reszty to zasada jest prosta - jak na coś narzekamy. to poprawiamy przy pierwszej okazji (jak tylko coś ruszamy w danym kodzie).
Jak ktoś w zespole narzeka ... no to znaczy, że trzeba go przekonać do naprawienia. Ogólnie narzekacze (nie wszyscy) to niezła moc zespołu - mogą projekt nieźle podciągnąć.


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 3x, ostatnio: jarekr000000
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)