Właściwe wstrzyknięcie beanów

0

Cześć,
mam pytanie o dobre praktyki programistyczne. W skrócie hipotetyczna sytuacja.
Mamy producentów oraz różne produkty które przypisane są do tych producentów.
Aby to zrealizować stworzyłem:
Encje - Producer
Encje - Product
między encjami jest relacja OneToMany.

Oprócz tego mam ProducerDao oraz ProductDao.
Przygotowałem również ProducerService oraz ProductService.

Chodzi mi o te ostatnie. Czy właściwym jest podejście, że w ProducerService stworze metode np. addProduct(Product product) która tak naprawde wykona metode z ProductDao czyli ProducerService będzie musiało mieć też dostęp do ProductDao?
Druga sprawa tak naprawde ta metoda addProduct powinna mieć dwa argumenty, Product oraz Producer do którego to należy przypisać?

Dzięki

0

Dobrze myślisz, service ma zazwyczaj referencję do dao. Jednak staraj się nie przejmować warstwą DAO - to tylko zapis do bazy, nic więcej. Zapisywanie do bazy to efekt uboczny, skup się na logice biznesowej i widoku.

A co do drugiego - nie ma przeszkody by zapisac sam przedmiot bez właściciela, dopóki nie masz ustawionego "nullable" na kolumnie (nie pamietam czy tak się nazywało...)

0
Biały Orzeł napisał(a):

Dobrze myślisz, service ma zazwyczaj referencję do dao. Jednak staraj się nie przejmować warstwą DAO - to tylko zapis do bazy, nic więcej. Zapisywanie do bazy to efekt uboczny, skup się na logice biznesowej i widoku.

Co masz na myśli pisząc aby skupić się na widoku?
Jeśli chodzi o logikę biznesową to masz na myśli te zależności które prezentowane są w *Service?
Da się jeszcze w jakiś sposób zaimplementować logikę biznesową jeśli chodzi o kontekst obiektu? Mam tu na myśli aby doprowadzić do sytuacji, że mając np. obiekt Producenta zrobić coś takiego:
$producer.addProduct(Product product)?
Tzn. że się da to wiem, ale czy tak się generalnie robi, czy jest to dobra praktyka oraz jak najlepiej tego dokonać. W tym momencie tak naprawde $producer odwołuje się do obiektu encji.

0

a nie powinieneś wstrzykiwac obiektu Product z service bo to inna warstwa ? Tzn wydaje mi sie ze w jednym service mozesz uzyc kilku roznych typow DOA w zaleznosci od potrzeb , ale w tym przypadku lepiej bedzie zrobic service Producer oraz Produkt bo bedziesz je tez wykorzystywac oddzielnie i je ze soba powiaz wg hierarchii, ale co ja tam wiem..

0

OK, mam jeszcze pytanie odnośnie tej przykładowej metody addProduct z ProducerService. Jeśli w Product nie ma np. ustawionego jeszcze Producera to wtedy taka metoda addProduct powinna mieć dwa argumenty Producer/Product?
Pamiętajcie że cały czas pytam w kontekście dobrych praktyk :).

Dzieki za pomoc
Pozdro

0

Jak ja to widzę :


@Entity
public class Producer {
	@Id
	@GeneratedValue
	long id;
	
	String name;
	@OneToMany(mappedBy="producer", cascade=CascadeType.ALL, orphanRemoval=true)
	List<Product> products;

	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public List<Product> getProducts() {
		return products;
	}

	public void setProducts(List<Product> products) {
		this.products = products;
	}
	
}


@Entity
public class Product {
	@Id
	@GeneratedValue
	long id;
	String name;
	@ManyToOne
	@JoinColumn
	Producer producer;
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Producer getProducer() {
		return producer;
	}
	public void setProducer(Producer producer) {
		this.producer = producer;
	}
	
	

}


Jak widać nadrzędnym obiektem jest Producer i to w nim ustawiasz Products (w liście), żeby działały zależności w prosty sposób :

Tworzysz Producera oraz listę Products. W Producer ustawiasz listę Products i są ustawione zależności. Jeśli usuniesz danego Producera to po ustawieniu Cascade.ALL usunie również Products przypisane do Producera. Jak chcesz inaczej to zrobić?

Możesz tworzyć oddzielnie Products jeśli Producer_id może przyjmować wartości null inaczej się to nie uda i potem dodać je do Producera poprzez ustawienie listy.

//Nie jestem w tym biegły - cały czas się uczę, więc to tylko sugestia

0

byle gdzie to daj i nie przejmuj się takimi rzeczami tylko programuj. ps nie stosujesz żadnych dtosów?

0
karolinaa napisał(a):

byle gdzie to daj i nie przejmuj się takimi rzeczami tylko programuj

Mi nie chodzi o wrzucanie byle gdzie tylko tak jak napisałem w pierwszym poście/pytaniu o dobre praktyki :).
Byle gdzie to wiem że można wrzucić ;)

0

Wszystkie te wzorce powstawały dawno temu. Ja tam by się teraz nimi tak bardzo nie przejmował :) JavaEE jest teraz zupełnie inna i ma inne możliwości. Zresztą można powiedzieć, że encja w stanie detached to DTO, a EntityManager to DAO. Ja się nawet zastanawiam, czy w prostych projektach jest sens pisać klasy serwisowe, czy nie połączyć ich z kontrolerem w jedno.

0

Nie napisałeś w jakiej Javie to chcesz robić, bo różnie to wygląda w zależności od środowiska.
Zakładając że uczysz się aktualnych rozwiązań to "addProduct" możesz dodać dowolnego z podanych serwisów.
Warstwa serwisów może wywoływać kilka DAO - jest to warstwa z którą komunikuje się kontroler.

Masz to mniej więcej tak:

  • warstwa widoku: JSP/JSF (HTML, CSS, JS)
  • warstwa kontrolera: Struts, servlet itd. (routing, walidacja nie-pustości)
  • warstwa serwisów: wysokopoziomowy punkt wywołania logiki biznesowej ("złóż zamówienie", "zarejestruj klienta")
    • wywoływane DAO nie muszą mieć ze sobą bezpośredniego związku (np. "złóż zamówienie": ProductDAO, ClientDAO)
  • warstwa encji/DTO/POJO: grupowanie danych, transport
  • warstwa DAO:
    • zapis/odczyt/wyszukanie/skasowanie danych z tabeli,
    • na wejściu/wyjściu encja/DTO/POJO,
    • wewnątrz wywołanie używanej technologii bazodanowej,
    • może odwoływać się do innych tabel (poprzez relacje encji - patrz post od @Rossik)

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