Korzystanie z DAO w kontrolerze - czy dobre rozwiązanie?

0

Czy zawsze powinniśmy robić warstwę usług, nawet jeśli tylko potrzebujemy tylko coś zapisać/odczytać do bazy? Czy może jednak w kontrolerze wstrzyknąć tylko interfejs DAO i ewentualnie obiekt usługi, który będziemy potrzebować. W przykładzie poniżej ProducRepository jest bardzo podobne do ProductService, więc wygląda, że się kod powtarza.

DAO - interfejs

package com.packt.webstore.domain.repository;

import java.util.List;
import java.util.Map;
import java.util.Set;

import com.packt.webstore.domain.Product;

public interface ProductRepository {

	List <Product> getAllProducts();
	
	Product getProductById(String productID);
	
	List<Product> getProductsByCategory(String category);

	Set<Product> getProductsByFilter(Map<String, List<String>> filterParams);
	
	void addProduct(Product product);		
}

 
DAO - implementacja
package com.packt.webstore.domain.repository.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.stereotype.Repository;

import com.packt.webstore.domain.Product;
import com.packt.webstore.domain.repository.ProductRepository;
import com.packt.webstore.exception.ProductNotFoundException;

@Repository
public class InMemoryProductRepository implements ProductRepository{
	
	private List<Product> listOfProducts = new ArrayList<Product>();
	
	public InMemoryProductRepository() {
		Product iphone = new Product("P1234","iPhone 5s", new BigDecimal(500));
	    iphone.setDescription("Apple iPhone 5s, smartfon z 4-calowym ekranem o rozdzielczoœci 640×1136 i 8-megapikselowym aparatem");
	    iphone.setCategory("smartfon");
	    iphone.setManufacturer("Apple");
	    iphone.setUnitsInStock(1000);

	    Product laptop_dell = new Product("P1235","Dell Inspiron", new BigDecimal(700));
	    laptop_dell.setDescription("Dell Inspiron, 14-calowy laptop (czarny) z procesorami Intel Core 3. generacji");
	    laptop_dell.setCategory("laptop");
	    laptop_dell.setManufacturer("Dell");
	    laptop_dell.setUnitsInStock(1000);

	    Product tablet_Nexus = new Product("P1236","Nexus 7", new BigDecimal(300));
	    tablet_Nexus.setDescription("Google Nexus 7 jest najl¿ejszym 7-calowym tabletem z 4-rdzeniowym procesorem Qualcomm Snapdragon™ S4 Pro");
	    tablet_Nexus.setCategory("tablet");
	    tablet_Nexus.setManufacturer("Google");
	    tablet_Nexus.setUnitsInStock(1000);

	    listOfProducts.add(iphone);
	    listOfProducts.add(laptop_dell);
	    listOfProducts.add(tablet_Nexus);

	}

	public List<Product> getAllProducts() {
		return listOfProducts;
	}

	public Product getProductById(String productId) {
		Product productById = null;
		
		for(Product product : listOfProducts) {
			if(product!=null && product.getProductId()!=null && product.getProductId().equals(productId)){
				productById = product;
				break;
			}
		}
		
		if(productById == null){
			throw new ProductNotFoundException("Brak produktu o wskazanym identyfikatorze: "+productId+".");
		}
		
		return productById;
	}
	
	public List<Product> getProductsByCategory(String category) {
		List<Product> productsByCategory = new ArrayList<Product>();
			
		for(Product product: listOfProducts) {
			if(category.equalsIgnoreCase(product.getCategory())){
				productsByCategory.add(product);
			}
		}
		
		return productsByCategory;
	}

	public Set<Product> getProductsByFilter(Map<String, List<String>> filterParams) {
		Set<Product> productsByBrand = new HashSet<Product>();
		Set<Product> productsByCategory = new HashSet<Product>();

		Set<String> criterias = filterParams.keySet();
		
		if(criterias.contains("brand")) {
			for(String brandName: filterParams.get("brand")) {
				for(Product product: listOfProducts) {
					if(brandName.equalsIgnoreCase(product.getManufacturer())){
						productsByBrand.add(product);
					}
				}
			}
		}
		
		if(criterias.contains("category")) {
			for(String category: filterParams.get("category")) {
				productsByCategory.addAll(this.getProductsByCategory(category));
			}
		}
		
		productsByCategory.retainAll(productsByBrand);
		
		return productsByCategory;
	}
	
	public void addProduct(Product product) {
		   listOfProducts.add(product);
	}

}

package com.packt.webstore.service;

import java.util.List;
import java.util.Map;
import java.util.Set;
Warstwa usług
import com.packt.webstore.domain.Product;

public interface ProductService {

	List<Product> getAllProducts();

	Product getProductById(String productID);
	
	List<Product> getProductsByCategory(String category);

	Set<Product> getProductsByFilter(Map<String, List<String>> filterParams);
	
	void addProduct(Product product);
}

package com.packt.webstore.service.impl;

import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.packt.webstore.domain.Product;
import com.packt.webstore.domain.repository.ProductRepository;
import com.packt.webstore.service.ProductService;
Implementacja usług.

@Service
public class ProductServiceImpl implements ProductService{
	
	@Autowired
	private ProductRepository productRepository;

	public List<Product> getAllProducts() {
		return productRepository.getAllProducts();
	}

	public Product getProductById(String productID) {
		return productRepository.getProductById(productID);
	}
	
	public List<Product> getProductsByCategory(String category) {
		return productRepository.getProductsByCategory(category);
	}

	public Set<Product> getProductsByFilter(Map<String, List<String>> filterParams) {
		return productRepository.getProductsByFilter(filterParams);
	}
	
	public void addProduct(Product product) {
		   productRepository.addProduct(product);
	}

}

1

No jak robisz generic cruda który tylko zapisuje i czyta z bazy to nie ma sensu robić dodatkowej pustej warstwy.

0

Wzorzec Encja na twarz i pchasz autorstwa Pawła Szulca... zapamiętać wrócić do wrzucania info o spotkaniach juga.... Dziś w Mleczarni Paweł wprowadza do Haskella. Tu masz opisane kiedy tego używać, a kiedy potrzeba warstwy serwisowej http://www.slideshare.net/paulszulc/architektura-to-nie-bzdura

0

Mam podobne dylematy. Kiepsko wygląda kod w którym w gruncie rzeczy przepisuje się EntityManagera... i to kilka razy. Mam takie wrażenie, że w API EntityManagera brakuje jakiegoś wydzielenia interfejsu dla zapytań i komend (CQRS). Przecież zwłaszcza dla zwykłych zapytań o dane to nie ma sensu. Dla mnie idealnie byłoby sięgać po dane bezpośrednio z kontrolera, a komendy powinny iść przez warstwę usług

7370915722.png

0

Tak trochę z innej beczki. A czy "ładne" jest wstrzykiwanie serwisów do innych serwisów jeśli ich potrzebujemy ? Chodzi mi głównie o problem cyklicznych zależności.

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