@scibi92 -> jeśli masz klasę A zależną od klasy B, która zależy od A, to to jest problem z designem obu klas. Może to oznaczać, że próbujesz rozbić na dwie klasy kod, który wybitnie powinien być w jednej, albo że jedna z klas zajmuje się czymś, czym wybitnie nie powinna się zajmować. Albo że tylko wydaje Ci się, że one muszą być ze sobą powiązane. Zupełnie przypadkiem niedawno dostałem identyczne pytanie związane z pewnym kawałkiem kodu. Aby rozwiązać problem, wystarczyło sprawić, by klasa B nie wiedziała, że gada z A, bo po drodze był interfejs. Innymi słowy, przemodelowałem problem, by sprowadzał się do zagadnienia "klasa B zależy od czegokolwiek, co potrafi dostarczyć jej potrzebne informacje", a potrzebną instancję dostawała po prostu jako argument metody, która miała coś policzyć. I problem się rozwiązał.
@Interpod -> zgadzam się, że argumentacja "coś jest krzywe, bo jego autor jest cymbałem" to nie jest żadna argumentacja, a niektóre posty mogły tak wyglądać. Jednak pojawiło się też trochę merytorycznych argumentów w całej dyskusji. Próba kompletnego opisu wymaga napisania artykułu i chyba w niedługim czasie do stworzenia takowego siądę, skoro jest potrzeba. Tutaj zasygnalizuję tylko kilka ważniejszych myśli:
- "przecież beany to POJO z annotacją" - to zależy od tego, do czego ta adnotacja Ci służy. Jeśli adnotacja sprawia, że niepozorna klasa zmienia się nagle w kombajn, który potrafi np. zarządzać transakcjami i robić inne ciekawe rzeczy, to zauważ, że to wtedy przestaje być POJO. Dlaczego? Bo to "POJO" nie jest w stanie istnieć i funkcjonować bez towarzyszącego mu silnika, który się tą adnotacją zajmie. Zabierzesz silnik, klasa jest niefunkcjonalna, albo działa zupełnie inaczej.
- w protokole HTTP chodzi o to, by odebrać żądanie, popatrzeć, co w nim siedzi i na tej podstawie wygenerować odpowiedź. Taka aplikacja musi na starcie stworzyć kilka obiektów opisujących "świat aplikacji", otworzyć połączenie sieciowe i czekać na chętnych do pogadania. Czy jest coś trudnego w tej koncepcji? Wg mnie nie ma - programy działające na podobnej zasadzie tworzą studenci na drugim roku studiów w ramach zajęć. Problem, który rozwiązują frameworki, to po prostu odpalenie potrzebnych serwisów i zaproponowanie programiście jakiegoś sposobu opisania, jak przetworzyć żądanie na odpowiedź. Jeśli nie znasz/nie rozumiesz problemu, który rozwiązuje dane narzędzie, to wszystko, co robisz, odnosisz do narzędzia i przestajesz sobie radzić w momencie, gdy narzędzie zaczyna Cię ograniczać (a prędzej czy później taka sytuacja się trafi).
Podam Ci przykład, jak można stać się niewolnikiem narzędzia. Był sobie kiedyś taki framework webowy Apache Wicket. Jego ideą było to, aby aplikacje webowe pisało się podobnie, jak aplikacje okienkowe. Innymi słowy, miałeś komponenty ze swoim stanem, który trzymany był w sesji, a framework sam zarządzał, by w przeglądarce wszystko się odświeżało. Brzmi obiecująco, prawda? Kłopot w tym, że framework - próbując rozwiązać problem tworzenia aplikacji webowych - próbował zrobić z protokołu HTTP coś, do czego ten nigdy nie był projektowany. Po prostu styl tworzenia aplikacji desktopowych i webowych to dwa różne światy. Z jednej strony framework niby separował Cię od całej warstwy webowej, z drugiej - i tak nie mogłeś jej uniknąć, bo wyciekała ona w wielu miejscach, powodując zgrzyty (np. sesja ważąca kilkadziesiąt megabajtów). A gdy na taki zgrzyt trafiłeś, to trudno było coś na to poradzić, bo... byłeś niewolnikiem filozofii narzędzia, która się nie sprawdzała i byłeś zdany na jej łaskę bądź niełaskę. Ten sam problem, tj. tworzenie aplikacji webowych, można było rozwiązać w inny sposób: nauczyć się podstaw protokołu HTTP oraz podstaw tworzenia front-endów i backendów. Ilość wiedzy do zdobycia podobna, a efekt końcowy o wiele lepszy.