javaoopdomain-driven-designdomain-model

Is DDD good for a search based application?


I'm learning about DDD.

But I don't know how can I apply DDD in my application. Almost of all my application have simple requirements. Just fetch data from API and restructure them. If there is more required data, call more API.

Example

Requirements : Search menus sold in opened restaurants(store) within a radius of 2 km Input : user's location
Provided API : search store API, store-open-time API(by store's id), menu API(by store's id)

  1. Fetch store list from search API by user's location.
  2. Filter store list by distance(within 2km)
  3. If there are stores satisfying its conditions, fetch the store-open-hour API.
  4. If there are opened stores, fetch menus from the menu API.
  5. If there are results, sort them at prices and reconstruct all the data you have.

Question

  1. I cannot extract Domain / Model in this case. what is the Domain entity?

  2. Here is my example code. But it seems to be bad. I think SearchMenuService is application service(not a domain service), but there are many logic. how can i fix the example code?

  3. If I want to fetch more data from rest api in a domain entity, is it possible? I think JPA can fetch more data by lazy loading.

@Service
public class SearchMenuService {
    private StoreRepository storeRepository;
    private OpenTimeRepository openTimeRepository;
    private MenuRepository menuRepository;

    @Transactional(readOnly = true)
    public ResultMenu getMenus(String location) {
        List<Store> stores = storeRepository.findStore(location);
        List<Store> nearStores = stores.stream().filter(store -> store.distance < 2000).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(nearStores)) {
            throw new NotFoundStoreException();
        }
        List<OpenTime> openTimes = openTimeRepository.findByStores(nearStores);
        List<Store> openStores = new ArrayList<>()
        for (int i = 0; i < nearStores.size(); i++) {
            LocalTime now = LocalTime.now();
            if (openTimes[i].open.isBefore(now) && openTimes[i].close.isAfter(now)) {
                openStores.add(nearStores[i])
            }
        }
        if (CollectionUtils.isEmpty(openStores)) {
            throw new NoOpenStoreException();
        }
        List<Menu> menus = menuRepository.findByStores(openStores)
                .stream()
                .sorted()
                .map(menu -> Pair.of(menu.storeName, menu))
                .collect(Collectors.toList());

        return new ResultMenu(menus);
    }
}

Is DDD not suitable for this application? I'm beginner of DDD. Thanks for your help.


Solution

  • Domain-driven design lends itself well to complex domains. A simpler domain or data capture application may not be a good fit. Where you have complex business rules a well defined domain may provide the mileage that one is after. Searching for data to display does not quite fit into a domain model since a domain is more concerned with the transactional/write/changing state side of things.

    For querying one would not typically use the domain objects. Aggregates should not be queried since, in all probability, they contain much more data than is required and the data may be encapsulated to such a degree that the relevant bits may not be available. A query layer may be more appropriate where you have closer access to raw data. In some instance you may employ read models but these are simple data transfer objects with no domain behaviour. This does not mean that you cannot make use of things such as specifications but these are more of a technical concern than a business one.