Discussion:
Application Services vs. Domain Services
Rickard Öberg
2010-02-22 02:17:05 UTC
Permalink
I am learning DDD but is somewhat confused about the difference between
Application Services and Domain Services.
I thought I understood Application Services that is fronts the Domain
Layer. My current understanding is that the Application Layer should not
contain any business rules and that it should be responsible for
specific application tasks. E.g. For example where the application is a
web service it would convert the web service data and calls and direct
it to the Domain Layer.
I would call that the "UI" layer, meaning, whatever it is that converts
the UI model (be it Swing, SOAP, JMS, etc.) to the application internal
model.

The Application Layer does this (DDD book, p.70):
"Defines the jobs the software is supposed to do and directs the
expressive domain objects to work out problems. The tasks this layer is
responsible for are meaningful to the business or necessary for
interactions with the application layers of other systems.
This layer is kept thin. It does not contain business rules or
knowledge, but only coordinates tasks and delegates work to
collaborations of domain objects in the next layer down. It does not
have state reflecting the business situation, but it can have state that
reflects the progress of a task for the user or the program."

There are a couple of ways to implement the application layer. One is to
use "application services", where the methods signify usecases. Another
approach that I'm personally growing very fond of is to use the DCI
pattern (complementary to MVC), which I have found significantly
simplifies my usecase code and permission checks, and such things. It
also happens to make it trivial to make REST API's properly.

<snip>
Here it seems that the Application Layer need to know a fair bit of what
is involved in booking new cargo, although arguably not that much and I
can still accept that is correct. But would the green section not make
more sense in the Domain Layer and make it still easier for the
Application Layer?
The really confusing part for me is the use of Repository access from
the Application layer and from the Domain layer.
Is the answer perhaps that the Domain layer should not be involved with
data access at all?
What I've found when using the DCI approach to the application layer,
the context will be doing the repository lookups, and the interaction
then triggers off the actual call into the domain model. I assume you'd
have to do something similar with an application service approach. So
yes, all lookups would be in the application layer, rather than the
domain layer.

/Rickard


------------------------------------
p_fourie
2010-02-21 14:07:39 UTC
Permalink
Hello,

I am learning DDD but is somewhat confused about the difference between
Application Services and Domain Services.

I thought I understood Application Services that is fronts the Domain
Layer. My current understanding is that the Application Layer should
not contain any business rules and that it should be responsible for
specific application tasks. E.g. For example where the application is a
web service it would convert the web service data and calls and direct
it to the Domain Layer.

However looking at the DDD Cargo sample application described in Eric
Evan's book the sample program's Application layer
(se.citerus.dddsample.application.impl) contains more logic in the
Application Layer than what I expected to see. I was surprised to
learn that this logic was not in the Domain Service.

Extract of BookingServiceImpl.bookNewCargo:

public TrackingId bookNewCargo(final UnLocode originUnLocode,
final UnLocode destinationUnLocode,
final Date arrivalDeadline) {

// TODO modeling this as a cargo factory might be suitable
final TrackingId trackingId = cargoRepository.nextTrackingId();
final Location origin =
locationRepository.find(originUnLocode);
final Location destination =
locationRepository.find(destinationUnLocode);
final RouteSpecification routeSpecification = new
RouteSpecification(origin,
destination,
arrivalDeadline);

final Cargo cargo = new Cargo(trackingId, routeSpecification);

cargoRepository.store(cargo);
logger.info("Booked new cargo with tracking id " +
cargo.trackingId().idString());

return cargo.trackingId();
}

Here it seems that the Application Layer need to know a fair bit of what
is involved in booking new cargo, although arguably not that much and I
can still accept that is correct. But would the green section not make
more sense in the Domain Layer and make it still easier for the
Application Layer?

The really confusing part for me is the use of Repository access from
the Application layer and from the Domain layer.
Is the answer perhaps that the Domain layer should not be involved with
data access at all?

Thank you,
Philip Fourie
Riccardo
2010-02-22 07:08:29 UTC
Permalink
application says "when"
repository is model
i think nothing strange happens...
application asks the model to store changes.. the per-interface approach let application to ignore infrastructure (mmm xml descriptors raise! annotations fall!)

as the other answer shows... ui calls application services to cover use case functions... (facade!)
Post by p_fourie
Hello,
I am learning DDD but is somewhat confused about the difference between
Application Services and Domain Services.
I thought I understood Application Services that is fronts the Domain
Layer. My current understanding is that the Application Layer should
not contain any business rules and that it should be responsible for
specific application tasks. E.g. For example where the application is a
web service it would convert the web service data and calls and direct
it to the Domain Layer.
However looking at the DDD Cargo sample application described in Eric
Evan's book the sample program's Application layer
(se.citerus.dddsample.application.impl) contains more logic in the
Application Layer than what I expected to see. I was surprised to
learn that this logic was not in the Domain Service.
public TrackingId bookNewCargo(final UnLocode originUnLocode,
final UnLocode destinationUnLocode,
final Date arrivalDeadline) {
// TODO modeling this as a cargo factory might be suitable
final TrackingId trackingId = cargoRepository.nextTrackingId();
final Location origin =
locationRepository.find(originUnLocode);
final Location destination =
locationRepository.find(destinationUnLocode);
final RouteSpecification routeSpecification = new
RouteSpecification(origin,
destination,
arrivalDeadline);
final Cargo cargo = new Cargo(trackingId, routeSpecification);
cargoRepository.store(cargo);
logger.info("Booked new cargo with tracking id " +
cargo.trackingId().idString());
return cargo.trackingId();
}
Here it seems that the Application Layer need to know a fair bit of what
is involved in booking new cargo, although arguably not that much and I
can still accept that is correct. But would the green section not make
more sense in the Domain Layer and make it still easier for the
Application Layer?
The really confusing part for me is the use of Repository access from
the Application layer and from the Domain layer.
Is the answer perhaps that the Domain layer should not be involved with
data access at all?
Thank you,
Philip Fourie
------------------------------------
jbenami1
2010-02-23 10:17:55 UTC
Permalink
Philip, I also find the separation between app and domain services hazy
in some circumstances. Rickard's book quote pretty well sums it up. I
tend to think of app services as encapsulating workflows, or processes,
that execute scenarios. These scenarios include processes that may be
outside the scope of the domain (like email notifications, security
checks, transactions), or that simply span many domain objects. The
domain-model should provide the means to easily run those scenarios.

In the case you outline, I would argue that it is not a clear-cut case
of an application service. The code you marked green could be
implemented in a cargo-factory.


Joni
Post by p_fourie
Hello,
I am learning DDD but is somewhat confused about the difference between
Application Services and Domain Services.
I thought I understood Application Services that is fronts the Domain
Layer. My current understanding is that the Application Layer should
not contain any business rules and that it should be responsible for
specific application tasks. E.g. For example where the application is a
web service it would convert the web service data and calls and direct
it to the Domain Layer.
However looking at the DDD Cargo sample application described in Eric
Evan's book the sample program's Application layer
(se.citerus.dddsample.application.impl) contains more logic in the
Application Layer than what I expected to see. I was surprised to
learn that this logic was not in the Domain Service.
public TrackingId bookNewCargo(final UnLocode originUnLocode,
final UnLocode destinationUnLocode,
final Date arrivalDeadline) {
// TODO modeling this as a cargo factory might be suitable
final TrackingId trackingId = cargoRepository.nextTrackingId();
final Location origin =
locationRepository.find(originUnLocode);
final Location destination =
locationRepository.find(destinationUnLocode);
final RouteSpecification routeSpecification = new
RouteSpecification(origin,
destination,
arrivalDeadline);
final Cargo cargo = new Cargo(trackingId, routeSpecification);
cargoRepository.store(cargo);
logger.info("Booked new cargo with tracking id " +
cargo.trackingId().idString());
return cargo.trackingId();
}
Here it seems that the Application Layer need to know a fair bit of what
is involved in booking new cargo, although arguably not that much and I
can still accept that is correct. But would the green section not make
more sense in the Domain Layer and make it still easier for the
Application Layer?
The really confusing part for me is the use of Repository access from
the Application layer and from the Domain layer.
Is the answer perhaps that the Domain layer should not be involved with
data access at all?
Thank you,
Philip Fourie
------------------------------------
vvernon_shiftmethod
2010-02-23 16:02:22 UTC
Permalink
Nice summary Joni. Looks like you aren't so new to DDD anymore.

Vaughn
Post by jbenami1
Philip, I also find the separation between app and domain services hazy
in some circumstances. Rickard's book quote pretty well sums it up. I
tend to think of app services as encapsulating workflows, or processes,
that execute scenarios. These scenarios include processes that may be
outside the scope of the domain (like email notifications, security
checks, transactions), or that simply span many domain objects. The
domain-model should provide the means to easily run those scenarios.
In the case you outline, I would argue that it is not a clear-cut case
of an application service. The code you marked green could be
implemented in a cargo-factory.
Joni
Post by p_fourie
Hello,
I am learning DDD but is somewhat confused about the difference
between
Post by p_fourie
Application Services and Domain Services.
I thought I understood Application Services that is fronts the Domain
Layer. My current understanding is that the Application Layer should
not contain any business rules and that it should be responsible for
specific application tasks. E.g. For example where the application is
a
Post by p_fourie
web service it would convert the web service data and calls and
direct
Post by p_fourie
it to the Domain Layer.
However looking at the DDD Cargo sample application described in Eric
Evan's book the sample program's Application layer
(se.citerus.dddsample.application.impl) contains more logic in the
Application Layer than what I expected to see. I was surprised to
learn that this logic was not in the Domain Service.
public TrackingId bookNewCargo(final UnLocode originUnLocode,
final UnLocode destinationUnLocode,
final Date arrivalDeadline) {
// TODO modeling this as a cargo factory might be suitable
final TrackingId trackingId = cargoRepository.nextTrackingId();
final Location origin =
locationRepository.find(originUnLocode);
final Location destination =
locationRepository.find(destinationUnLocode);
final RouteSpecification routeSpecification = new
RouteSpecification(origin,
destination,
arrivalDeadline);
final Cargo cargo = new Cargo(trackingId, routeSpecification);
cargoRepository.store(cargo);
logger.info("Booked new cargo with tracking id " +
cargo.trackingId().idString());
return cargo.trackingId();
}
Here it seems that the Application Layer need to know a fair bit of
what
Post by p_fourie
is involved in booking new cargo, although arguably not that much and
I
Post by p_fourie
can still accept that is correct. But would the green section not
make
Post by p_fourie
more sense in the Domain Layer and make it still easier for the
Application Layer?
The really confusing part for me is the use of Repository access from
the Application layer and from the Domain layer.
Is the answer perhaps that the Domain layer should not be involved
with
Post by p_fourie
data access at all?
Thank you,
Philip Fourie
------------------------------------
jbenami1
2010-02-24 11:05:55 UTC
Permalink
Thanks!


Joni
Post by vvernon_shiftmethod
Nice summary Joni. Looks like you aren't so new to DDD anymore.
Vaughn
Post by jbenami1
Philip, I also find the separation between app and domain services hazy
in some circumstances. Rickard's book quote pretty well sums it up. I
tend to think of app services as encapsulating workflows, or
processes,
Post by vvernon_shiftmethod
Post by jbenami1
that execute scenarios. These scenarios include processes that may be
outside the scope of the domain (like email notifications, security
checks, transactions), or that simply span many domain objects. The
domain-model should provide the means to easily run those scenarios.
In the case you outline, I would argue that it is not a clear-cut case
of an application service. The code you marked green could be
implemented in a cargo-factory.
Joni
Post by p_fourie
Hello,
I am learning DDD but is somewhat confused about the difference
between
Post by p_fourie
Application Services and Domain Services.
I thought I understood Application Services that is fronts the Domain
Layer. My current understanding is that the Application Layer should
not contain any business rules and that it should be responsible for
specific application tasks. E.g. For example where the
application is
Post by vvernon_shiftmethod
Post by jbenami1
a
Post by p_fourie
web service it would convert the web service data and calls and
direct
Post by p_fourie
it to the Domain Layer.
However looking at the DDD Cargo sample application described in Eric
Evan's book the sample program's Application layer
(se.citerus.dddsample.application.impl) contains more logic in the
Application Layer than what I expected to see. I was surprised to
learn that this logic was not in the Domain Service.
public TrackingId bookNewCargo(final UnLocode originUnLocode,
final UnLocode
destinationUnLocode,
Post by vvernon_shiftmethod
Post by jbenami1
Post by p_fourie
final Date arrivalDeadline) {
// TODO modeling this as a cargo factory might be suitable
final TrackingId trackingId =
cargoRepository.nextTrackingId();
Post by vvernon_shiftmethod
Post by jbenami1
Post by p_fourie
final Location origin =
locationRepository.find(originUnLocode);
final Location destination =
locationRepository.find(destinationUnLocode);
final RouteSpecification routeSpecification = new
RouteSpecification(origin,
destination,
arrivalDeadline);
final Cargo cargo = new Cargo(trackingId,
routeSpecification);
Post by vvernon_shiftmethod
Post by jbenami1
Post by p_fourie
cargoRepository.store(cargo);
logger.info("Booked new cargo with tracking id " +
cargo.trackingId().idString());
return cargo.trackingId();
}
Here it seems that the Application Layer need to know a fair bit of
what
Post by p_fourie
is involved in booking new cargo, although arguably not that much and
I
Post by p_fourie
can still accept that is correct. But would the green section not
make
Post by p_fourie
more sense in the Domain Layer and make it still easier for the
Application Layer?
The really confusing part for me is the use of Repository access from
the Application layer and from the Domain layer.
Is the answer perhaps that the Domain layer should not be involved
with
Post by p_fourie
data access at all?
Thank you,
Philip Fourie
------------------------------------

chris_gardner76
2010-02-22 15:21:11 UTC
Permalink
Rickard,

Is this the DCI of which you speak?

http://www.artima.com/articles/dci_vision.html
Post by Rickard Öberg
I am learning DDD but is somewhat confused about the difference between
Application Services and Domain Services.
I thought I understood Application Services that is fronts the Domain
Layer. My current understanding is that the Application Layer should not
contain any business rules and that it should be responsible for
specific application tasks. E.g. For example where the application is a
web service it would convert the web service data and calls and direct
it to the Domain Layer.
I would call that the "UI" layer, meaning, whatever it is that converts
the UI model (be it Swing, SOAP, JMS, etc.) to the application internal
model.
"Defines the jobs the software is supposed to do and directs the
expressive domain objects to work out problems. The tasks this layer is
responsible for are meaningful to the business or necessary for
interactions with the application layers of other systems.
This layer is kept thin. It does not contain business rules or
knowledge, but only coordinates tasks and delegates work to
collaborations of domain objects in the next layer down. It does not
have state reflecting the business situation, but it can have state that
reflects the progress of a task for the user or the program."
There are a couple of ways to implement the application layer. One is to
use "application services", where the methods signify usecases. Another
approach that I'm personally growing very fond of is to use the DCI
pattern (complementary to MVC), which I have found significantly
simplifies my usecase code and permission checks, and such things. It
also happens to make it trivial to make REST API's properly.
<snip>
Here it seems that the Application Layer need to know a fair bit of what
is involved in booking new cargo, although arguably not that much and I
can still accept that is correct. But would the green section not make
more sense in the Domain Layer and make it still easier for the
Application Layer?
The really confusing part for me is the use of Repository access from
the Application layer and from the Domain layer.
Is the answer perhaps that the Domain layer should not be involved with
data access at all?
What I've found when using the DCI approach to the application layer,
the context will be doing the repository lookups, and the interaction
then triggers off the actual call into the domain model. I assume you'd
have to do something similar with an application service approach. So
yes, all lookups would be in the application layer, rather than the
domain layer.
/Rickard
------------------------------------
Rickard Öberg
2010-02-23 02:24:03 UTC
Permalink
Post by chris_gardner76
Rickard,
Is this the DCI of which you speak?
http://www.artima.com/articles/dci_vision.html
<http://www.artima.com/articles/dci_vision.html>
It is. I've implemented the DCI concepts in Qi4j now, and it really
helps with many important concepts. From what I can see it gives a more
object-oriented way to implement application services, it gives a more
natural way to do permission checking, makes it easier to handle
aggregate rules, and also makes it trivial to expose a REST API (in the
Roy Fielding sense). The last one is because the context stack naturally
maps to URL's (each "/segment/" becomes a context with interactions).
It's pretty neat.

/Rickard


------------------------------------
p_fourie
2010-02-22 17:09:27 UTC
Permalink
Hi Rickard,

Thanks for taking the time to explain, it is much appreciated.
Also thanks for the tip on DCI, will explore that option further.

Thank you,
Philip
Post by Rickard Öberg
I am learning DDD but is somewhat confused about the difference between
Application Services and Domain Services.
I thought I understood Application Services that is fronts the Domain
Layer. My current understanding is that the Application Layer should not
contain any business rules and that it should be responsible for
specific application tasks. E.g. For example where the application is a
web service it would convert the web service data and calls and direct
it to the Domain Layer.
I would call that the "UI" layer, meaning, whatever it is that converts
the UI model (be it Swing, SOAP, JMS, etc.) to the application internal
model.
"Defines the jobs the software is supposed to do and directs the
expressive domain objects to work out problems. The tasks this layer is
responsible for are meaningful to the business or necessary for
interactions with the application layers of other systems.
This layer is kept thin. It does not contain business rules or
knowledge, but only coordinates tasks and delegates work to
collaborations of domain objects in the next layer down. It does not
have state reflecting the business situation, but it can have state that
reflects the progress of a task for the user or the program."
There are a couple of ways to implement the application layer. One is to
use "application services", where the methods signify usecases. Another
approach that I'm personally growing very fond of is to use the DCI
pattern (complementary to MVC), which I have found significantly
simplifies my usecase code and permission checks, and such things. It
also happens to make it trivial to make REST API's properly.
<snip>
Here it seems that the Application Layer need to know a fair bit of what
is involved in booking new cargo, although arguably not that much and I
can still accept that is correct. But would the green section not make
more sense in the Domain Layer and make it still easier for the
Application Layer?
The really confusing part for me is the use of Repository access from
the Application layer and from the Domain layer.
Is the answer perhaps that the Domain layer should not be involved with
data access at all?
What I've found when using the DCI approach to the application layer,
the context will be doing the repository lookups, and the interaction
then triggers off the actual call into the domain model. I assume you'd
have to do something similar with an application service approach. So
yes, all lookups would be in the application layer, rather than the
domain layer.
/Rickard
------------------------------------
Loading...