Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Assume we are developing a REST system for an enterprise company to expose the companies resources in a Java based application. Ultimately you have one web application, and domain libraries. My question is to where components and services should live in these domain libraries and what should exist in the application itself.

For a hypothetical company we may have several domain areas.

  • Customer Relations
  • Customer Sales Orders
  • Manufacturing
  • Product Structure
  • Supply Chain
  • Warehousing

Given these domains we would have domain objects and object services for persistence. We could then further separate these into implementations

  • Customer Relations
  • Customer Relations - JDBC Impl
  • Customer Sales Orders
  • Customer Sales Orders - JDBC Impl
  • Manufacturing
  • Manufacturing - JDBC Impl
  • Product Structure
  • Product Structure - JDBC Impl
  • Supply Chain
  • Supply Chain - JDBC Impl
  • Warehousing
  • Warehousing - JDBC Impl

Now it's starting to look complex only because of how many individual libraries we are managing. I'm wondering if we even need to separate to such a level and could simply have the three.

  • Business - Interface
  • Business - JDBC Impl
  • REST Application

My second part of my question relates to where service classes and management classes should live. Given our Warehousing above we need domain objects to represent pick-faces, a DAO class to manage the pick-face object and finally a service component for our rest application. For this we could see the following structure.

  • Warehousing
    • PickFace
    • PickFaceDAO
  • Warehousing - JDBC Impl
    • JdbcPickFaceDAO
  • ReST application
    • PickFaceController

On the one hand PickFaceController is best inside the ReST application as the application can then manage the services for this controller manually and may need to customise configuration.

But, on the other hand the PickFaceController might be better inside the Warehousing project as it's only concerned to the warehousing module, yet the ReST application could theoretically use service locators to find services in other libraries.

SO what are the successful approaches being used? When do you know when you've gone to far in separating or not done enough? How do you know the best place to put something?

share|improve this question
add comment

1 Answer 1

up vote 5 down vote accepted

You should take a look at Onion Architecture - it works very well when with domain driven design.

In summary, the Onion Architecture advocates that you layer your application least-dependent/longest-living to most-dependent/shortest-living. Your domain classes with repository interfaces would remain inside the core while the specific implementations would reside in an outer layer.

Typically, you would have something like this (top has no dependencies, all below depends on what's above):

  • Common/Shared core functionality
  • Core Layer - Domain Models, Domain Services, Interfaces
  • Application Layer - Orchestration and anti-corruption layer
  • Infrastructure Layer - Typically concrete implementations of domain interfaces
  • Presentation Layer

The idea here is that the Common/Shared core functionality is available everywhere (mostly helpers, shouldn't contain domain logic per se).

The Application and Infrastructure Layers would depend on the Core Layer and Common/Shared core functionality.

The Presentation Layer would depend on the Application, Infrastructure and Common/Shared core Layers but not directly ontop of the Core Layer to ensure anti-corruption.

There might be more than one Application Layer - This depends on how many endpoints you might have (one Application Layer might be a Web Service). You don't want your presentation layer to depend directly upon your Core Domain Models because it voilates the single responsibility principal (domain logic should apply to domain models - given the domain objects the responsibility of data transfer objects imposes certain limitations upon implementation of domain logic).

I hope that guidance is of worth to you. I can't make the judgement of exactly how you should split up your project into different libraries because that would depend on other factors.

In the end there's nothing stopping you from putting all of it inside a single assembly. You would typically split them up by bounded context (self-contained) in order to ensure dependency inversion on a logical separation level. There are also utilities available out there to combine multiple libraries into a single one for deployment.

share|improve this answer
    
Thanks Shelakel, very worthy information. I am aware of using a layered approach, when I'm most interested in is if I should be separating each domain, such as sales orders and warehousing equating in two interface and two implementation modules, or should they be combined to one? Each way IMHO has it's own advantages but I'm still on the fence with this part. –  Brett Ryan Aug 27 '12 at 1:08
    
I'm glad you have found it useful. I see that most projects start out with a very generic project structure (Interfaces, Repositories, Models) and then get refactored into bounded-contexts (Sales, Warehousing). By doing the same, you cover all scenarios in a very generic manner and you will also provide structure (so that you will know where what should go). Just be wary that by doing so, you might hide code smells (especially i.t.o SRP). If you can't be assured that discipline will be maintained, you can jump straight into the latter - the key is concistency. –  Shelakel Aug 27 '12 at 6:03
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.