Spring jednak utrudnia pisanie poprawnego kodu obiektowego. Człowiek chce napisać normalną klasę, która posiada dane i bazujące na nich zachowania, ale nie da się w prosty sposób. Jeśli chcemy dodać dane instancji, to najłatwiej to zrobić przez new, ale wtedy obiekt nie będzie zarządzany przez Springa i nie da się wstrzyknąć do niego zależności. Jedyne rozwiązanie, jakie widzę, to wstrzyknąć pustego beana ze scope "prototype", a później przez setery poustawiać mu wszystkie dane, ale to bardzo zaśmieca kod i uniemożliwia tworzenie niemutowalnych klas, których jestem zwolennikiem.
@diabel_z_piekla: właśnie chyba nie do końca. Ja chcę tworzyć wiele instancję klasy z różnymi danymi (z mojego punktu widzenia nie muszą to być wcale beany springowe) wewnątrz której mógłbym wstrzyknąć też zależności, ale to nie jest możliwe bez sporej gimnastyki.
@witajswiecie: tak, przykład na pastebin jest takim udawaniem, ale jak pisałem w którymś komentarzu, w tej klasie pojawiłyby się dodatkowe metody, które na podstawie danych instancji i zewnętrzych zależności wykonują różne akcje (czyli prawdziwa klasa, która wiąże dane z zachowaniem). Przykład napisany był na szybko na kolanie, żeby zobrazować problem.
@dog_meat: Nie przeczytałem wszystkich komentarzy ale można zrobić obiekt przez new i ręcznie go dodać do kontenera, jak również można ręcznie z kontenera sobie wyciągnąć zależności, które się chce, nie trzeba korzystać z autowired albo component skanu, żey mieć zależności.
@dog_meat: No ale nadal możesz tworzyć wiele instancji. Z Twojego przypadku, factory które opisałem:
List createPearsonList() { List list = new ArrayLis<>(); for(int i=0; i<10; ++i) { Pearson p = new Pearson("name"+i, "lastName" + i, "city" +i, i); beanFacory.autowireBean(p); list.add(p); } return list; } Każdy element listy będzie miał inne dane przekazane w konstruktorze, a spring wstrzyknie zależności.
@witajswiecie: w sumie z kontekstem Springa w konstruktorze też nie jest złe rozwiązanie. A argumenty implicit w Scali właśnie myślę, że wiele dają. To, że one tam są w niczym nie przeszkadza. Kod robi się czytelniejszy, bo tworząc instancję przekazujemy tylko dane instancji, bez zależności, co moim zdaniem bardzo zwiększa czytelność. A nawet bez tego, nawet samo to, że można tworzyć wiele list argumentów też zwiększa czytelność, bo można je logicznie
@dog_meat: w Springu mamy klasę org.springframework.web.context.support.SpringBeanAutowiringSupport powinna załatwić sprawę :)
i nie jestem przekonany co do tego wzrostu czytelności, dobry przykład to wykorzystanie ExecutionContext (ExecutionContext.global albo jakiegoś customowego) przy tworzeniu Future w scali, niby fajne że parametrów robi się dzięki temu mniej, ale tak na dobrą sprawę określenie na czym dokładnie wykona się dany wątek wymaga patrzenia w importy bo nie mamy w sposób jawny widocznego jaki executor i z jaką
@witajswiecie: jak dla mnie to jest właśnie bardzo czytelne (jeśli się, wie, gdzie szukać implicitów), ale to pewnie kwestia gustu. A do tego, chyba jedna z ostatnich wersji Idei potrafi pokazywać implicity.
Moja propozycja - zrezygnuj z dodawania czegokolwiek "że Sprintach" w swojej "normalnej klasie". Nie wymyślaj koła na nowo, dostosuj się do Springa. Jak? Dane przechowuj w obiektach swojej klasy, oczywiście z setterami i getterami. Logikę biznesowa związana z nimi przenieś do @Service, które operować będzie na całych obiektach. Nie widzę sensu żeby na siłę łączyć to wszystko. Sam używam zawsze takich rozwiązań i oddzielam logikę od danych tworząc im dedykowane części
@Koryntiusz: no pisałem o tym kilka razy. OOP opiera się przede wszystkim na łączeniu w klasie danych i zachowań. Wskaż mi prosty przykład, jak można utworzyć w łatwy sposób bean z indywidualnymi danymi instancji który jest immutable
@ragreenpl: no pisałem już wielokrotnie. OOP opiera się na tym że w jednej klasie zawieramy dane i bazujące na nich zachowania. Jesli znasz definicję programowania obiektowego, które nie opiera się na takim założeniu wskaż proszę źródło. A to, co proponuje spring, to właśnie programowanie strukturalne, które tylko udaje oboektowe (czyli serwisy bez indywidualnych danych instancji) i klasy tylko na dane (anemiczny model dziedziny, który jest antywzorcem)
@Koryntiusz: jak przeczytasz pierwszy komentarz, to zobaczysz, że wpis nie dotyczył tego, czy chcę używać Springa, czy nie, a jedynie stwierdzenie, że Spring promuje programowanie strukturalne i zniechęca do dobrych praktyk programowania obiektowego
@dog_meat: Skoro Ci to przeszkadza to rezygnujesz że springa. Spring powstał jako IoC container i beany z założenia mają być bezstanowe, dlatego domyślnie są singletonami - bo nie trzeba ich tworzyć kilku skoro są bezstanowe. Możesz tworzyć beany typu requested i będziesz miał nowego przy każdym zapytaniu.
@Koryntiusz: no tak. Czyli to, o czym piszę cały czas, architektura Springa została zaprojektowana tak, żeby promować programowanie strukturalne i mocno utrudniać programowanie oboektowe
@Koryntiusz: nie mówię, że robili to z takim zamysłem. Oczywiście, że programowanie oboektowe ma jesscze inne cechy, natomiast każda definicja wychodzi z tego, że jest to paradygmat, które wiąże dane z zachowaniami i na tym opiera resztę, jest to fundament OOP.
@dog_meat: Dla odświeżenia poczytałem parę definicji i żadna się od tego nie zaczynała ;) W każdym razie czego jeszcze oczekujesz? Spring działa jak działa jak chcesz go używa to musisz się dostosować. Swoją drogą pokaż mi inny framework który robi dependency injection i działa tak jak byś chciał?
@Koryntiusz: a z ciekawości, od czego się zaczynają te definicje? Bo tam gdzie sprawdzałem, zaczynają się od tego.
Wydaje mi się, że Guice działa blisko tego. Nie wiem, jak w Javie, ale ostatnio pracowałem głównie w Scali i tam razem z Guice dawało się to osiągnąć (chociaż też potrzebna była gimnastyka).
ogólnie to nie oczekuję niczego. Bardziej napisałem to pod wpływem tego, że wróciłem ostatnio do Javy, próbowałem pisać zgodnie z
Dymy kończą się tam, gdzie komuś może stać się realna krzywda. To co zrobił Tyburski były bardzo niebezpieczne i jako koneserowi patologi jest mi smutno. Należy to potępić.
Spring jednak utrudnia pisanie poprawnego kodu obiektowego. Człowiek chce napisać normalną klasę, która posiada dane i bazujące na nich zachowania, ale nie da się w prosty sposób.
Jeśli chcemy dodać dane instancji, to najłatwiej to zrobić przez new, ale wtedy obiekt nie będzie zarządzany przez Springa i nie da się wstrzyknąć do niego zależności.
Jedyne rozwiązanie, jakie widzę, to wstrzyknąć pustego beana ze scope "prototype", a później przez setery poustawiać mu wszystkie dane, ale to bardzo zaśmieca kod i uniemożliwia tworzenie niemutowalnych klas, których jestem zwolennikiem.
List createPearsonList() {List list = new ArrayLis<>();
for(int i=0; i<10; ++i) {
Pearson p = new Pearson("name"+i, "lastName" + i, "city" +i, i);
beanFacory.autowireBean(p);
list.add(p);
}
return list;
}
Każdy element listy będzie miał inne dane przekazane w konstruktorze, a spring wstrzyknie zależności.
A argumenty implicit w Scali właśnie myślę, że wiele dają. To, że one tam są w niczym nie przeszkadza. Kod robi się czytelniejszy, bo tworząc instancję przekazujemy tylko dane instancji, bez zależności, co moim zdaniem bardzo zwiększa czytelność. A nawet bez tego, nawet samo to, że można tworzyć wiele list argumentów też zwiększa czytelność, bo można je logicznie
w Springu mamy klasę org.springframework.web.context.support.SpringBeanAutowiringSupport
powinna załatwić sprawę :)
i nie jestem przekonany co do tego wzrostu czytelności,
dobry przykład to wykorzystanie ExecutionContext (ExecutionContext.global albo jakiegoś customowego) przy tworzeniu Future w scali, niby fajne że parametrów robi się dzięki temu mniej, ale tak na dobrą sprawę określenie na czym dokładnie wykona się dany wątek wymaga patrzenia w importy bo nie mamy w sposób jawny widocznego jaki executor i z jaką
@dog_meat: A może mieszasz logikę biznesową ze wzorcami projektowymi?
Gdzie serwis w sparingu jest niezgodny z OOP?
Spring powstał jako IoC container i beany z założenia mają być bezstanowe, dlatego domyślnie są singletonami - bo nie trzeba ich tworzyć kilku skoro są bezstanowe. Możesz tworzyć beany typu requested i będziesz miał nowego przy każdym zapytaniu.
Wiesz że OOP mówi o kilku zasadach? Np. dziedziczeniu, polimorfizmie, enkapsulacji?
W każdym razie czego jeszcze oczekujesz? Spring działa jak działa jak chcesz go używa to musisz się dostosować. Swoją drogą pokaż mi inny framework który robi dependency injection i działa tak jak byś chciał?
Wydaje mi się, że Guice działa blisko tego. Nie wiem, jak w Javie, ale ostatnio pracowałem głównie w Scali i tam razem z Guice dawało się to osiągnąć (chociaż też potrzebna była gimnastyka).
ogólnie to nie oczekuję niczego. Bardziej napisałem to pod wpływem tego, że wróciłem ostatnio do Javy, próbowałem pisać zgodnie z