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, botów: 0