2015-07-31 43 views
6

staram się uzyskać odpowiedzi na dwa dość podobne pytania tutaj:Czy należy przekonwertować obiekt na DTO w obiekcie repozytorium i zwrócić go do warstwy usługi?

Mam konwersji podmiot do DTO wewnątrz repozytorium obiektów i odesłać go do warstwy usługi?

lub

Czy mogę powrócić DTO obiektów z repozytorium warstwy?

W tej chwili utknąłem w moim Servlet (Warstwa Servie), że np. stara się odzyskać wszystkie Restaurant obiektów z RestaurantOwnerRepository:

// RestaurantOwnerService (Servlet) 

@Override 
@Transactional 
public List<RestaurantDTO> getAvailableRestaurants() { 

    List<Restaurant> availableRestaurants = restaurantOwnerRepository.getRestaurants(getSessionId()); 

    return null; 
} 

gdzie Restaurant jest @Entity adnotacją klasa - co wydaje się być pierwszą rzeczą, jaką należy zrobić, ponieważ nie warstwie usług ma teraz wiedzieć o bardzo niskim poziomie obiekt, który imho narusza próbę abstrakcji moich danych w każdej warstwie.

To nie byłoby tak, gdy ja np. przekonwertować każdy Restaurant na RestaurantDTO - ale czy powinienem to zrobić?

Zasadniczo zmienić:

// RestaurantOwnerRepository 

@Override 
public List<Restaurant> getRestaurants(String sessionId) { 

    RestaurantOwner restaurantOwner = this.get(sessionId); 

    // .. getting restaurants .. 

    return availableRestaurants; 
} 

do

// RestaurantOwnerRepository 

@Override 
public List<Restaurant> getRestaurants(String sessionId) { 

    RestaurantOwner restaurantOwner = this.get(sessionId); 

    // .. getting restaurants .. 

    return ConvertEntity.convertRestaurants(availableRestaurants); 
} 

i mają util ConvertEntity dla każdy podmiot takiego na przykład:

public class ConvertEntity { 

    public static List<RestaurantDTO> convertRestaurants(List<Restaurant> restaurants) { 
     // ... 
    } 

} 

ale to po prostu nie czuje jak najlepsze rozwiązanie dla mnie .. co co uld Mam tutaj?


Ważne jest, aby wspomnieć byłoby, że to pochodzi tworzą projekt GWT. Oznacza to, że używam np. RestaurantDTO na serwerze i po stronie klienta, ponieważ jest on zawarty w projekcie współdzielonym.

+0

Twoje drugie pytanie musi być * "Czy można zwrócić ** jednostki ** z warstwy repozytorium?" *, Prawda? Ponadto, czy mógłbyś sprawdzić swoje typy zwrotu? Jestem nieco zdezorientowany, np. w Twoim trzecim fragmencie. – sp00m

+0

Stwórz interfejs DTO i pozwól, aby "Restauracja" go zaimplementował. Podmiot i DTO i tak podzielą większość wdrożenia. –

+0

Po prostu zwróć go do warstwy usługi. – Stefan

Odpowiedz

9

Po komentarzu jest już wyraźniej. Spróbujmy jeszcze raz:

początek kilka wyjaśnień: Twój RestaurantOwnerRepository realizuje repozytorium wzór. Twoje obiekty oznaczone adnotacją są obiektami hibernacji, a także proxy DAO. Twoja RestaurantOwnerService jest usługą GWT, która może zwrócić tylko DTO udostępnionego klientowi i serwerowi.

więc w bardzo prosty stronie serwera konfiguracji, masz DB-backend, dostęp do danych poprzez Hibernate jako warstwy trwałości i warstwę usług jak usługi REST. W takiej konfiguracji twoje jednostki hibernacji są dzielone na cały kod po stronie serwera. Twoja warstwa usługowa konwertuje jednostki na format json, na przykład. Sprawa?

Twój "zaawansowany" setup

  • Trwałość warstwa
    • z hibernacji (dostarczającej @ Entity-Opatrzone komentarzem obiektów)
    • może inne rzeczy, zbyt
  • Repository Warstwa (niejasne dla ciebie, co do zwrotu)
  • warstwie usług (GWT Servlety, dostarczając DTOs które są udostępnione na stronie klienta)

Definicja Repository-Layer: Moim zdaniem, jest to abstrakcja dla różnych warstw danych/utrwalania. Nie zapewnia logiki biznesowej, która jest bardziej celem kolejnej warstwy biznesowej. Warstwa biznesowa kompiluje dane wyjściowe górnej warstwy, tworzy obliczenia i zwraca wyniki. Ale patrząc na twój komentarz, może to również dotyczyć twojej warstwy repozytorium. Ale to jest w porządku dla naszego wyjaśnienia.

Twoje pytanie: Czy można zwrócić obiekty DTO z warstwy repozytorium?

Odpowiedź: Odpowiedź: Nie jest to naprawdę w porządku, aby zwrócić DTO z warstwy "repozytorium".

Dlaczego: 1. Twoje DTO to domena przeniesiona do formatu, który można wysłać do klienta. Ma ograniczenia, więc niektórych bibliotek po stronie serwera nie można w nich używać. 2. Rozważ przypadek, że chcesz również zapewnić inne warstwy usług. Być może interfejs REST może być inny GUI-Framework. Wszystkie mają swoje własne ograniczenia dotyczące przenoszenia domen. Czy na pewno chcesz zduplikować warstwę repozytorium dla każdej warstwy usługi? 3. Rozważ przypadek, w którym chcesz rozszerzyć warstwę repozytorium/biznes tak, aby korzystała z wyjścia Twojego RestaurantOwnerRepository. Czy naprawdę chcesz pracować w DTO?

Dlatego tworzenie DTO jest celem warstwy usług. Tak więc DTO jest udostępniane po stronie klienta i twojej warstwie usług. W tym samym sensie potrzebujesz obiektów współużytkowanych między warstwą usługi i warstwą repozytorium. Wzywam te podmioty domeny. Są one zwracane z warstwy repozytorium i używane przez warstwę usługi. To samo dotyczy warstwy repozytorium i warstwy trwałości. Na przykład warstwa trwałości zwraca jednostki hibernacji, które są używane w warstwie repozytorium.

W większości przypadków dobrze jest propagować obiekty z wielu warstw w dół. Możesz więc przywrócić swoje hibernacje z poziomu repozytorium do warstwy usługi. Nowsze wersje GWT pozwalają nawet na użycie jednostek JPA po stronie klienta dzięki specjalnej konfiguracji. Tak więc twoja warstwa usług może dodatkowo zwrócić twoje jednostki trwałości.

+0

No cóż, żadna 'RestaurantOwnerRepository' nie jest tak naprawdę repozytorium (wzorzec). Każda opisana klasa '@ Entity' jest faktycznie DAO, ponieważ Hibernate owija proxy wokół niej. Nie rozumiem, dlaczego miałbym dzielić się klasami "@ Entity" w całym moim projekcie? Tylko serwer powinien o nich wiedzieć, a ich użycie kończy się warstwą repozytorium. Nie rozumiem także, co masz na myśli przez "kompilowanie obiektów repozytorium". Czy warstwa Repository Layer nie powinna zwracać obiektów biznesowych, które są już kompilacjami obiektów encji? – displayname

+0

zgodnie z twoim komentarzem, zredagowałem moją odpowiedź. Mam nadzieję, że teraz jest bardziej przejrzyste. – fatih

+0

Nie widziałem Twojej edycji, ponieważ nie powiadomiłeś mnie o @stefanfalk, ale dziękuję za rozszerzoną odpowiedź! Myślę, że rozumiem i ma to sens, dlaczego warstwa repozytorium nie powinna teraz zwracać DTO! – displayname