[#type-of-domain-objects]
= Type of Domain Objects

:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR  CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
:page-partial:


Apache Isis supports recognises four main types of domain classes:

* *domain entities* - domain objects persisted to the database the ORM (eg  JDO/DataNucleus); for example `Customer`

* *domain services* - generally singletons, automatically injected, and providing various functionality; for example `CustomerRepository`

* *view models* - domain objects that are a projection of some state held by the database, in support a particular use case; for example `CustomerDashboard` (to pull together commonly accessed information about a customer).

* *mixins* - allow functionality to be "contributed" in the UI by one module to another object, similar to traits or extension methods provided in some programming languages.
This is an important capability to help keep large applications decoupled.

From the end-user's perspective the UI displays a single domain object instance that has state (that is, a domain entity or a view model) per page.
The end-user can then inspect and modify its state, and navigate to related objects.

Domain classes are generally recognized using annotations.
Apache Isis defines its own set of annotations, and
you can generally recognize an Apache Isis domain class because it will be probably be annotated using `@DomainObject` and `@DomainService`.

The framework also recognises some annotations from the ORM layer (eg JDO/DataNucleus) and infers domain semantics from these annotations.
Similarly, JAXB annotations are typically used for view models.

The framework also defines supplementary annotations, notably xref:refguide:applib:index/annotation/DomainObjectLayout.adoc[@DomainObjectLayout] and xref:refguide:applib:index/annotation/DomainServiceLayout.adoc[@DomainServiceLayout].
These provide hints relating to the layout of the domain object in the user interface.
Alternatively, these UI hints might be defined in a supplementary xref:userguide:fun:ui.adoc#object-layout[.layout.xml] file.



[#domain-entities]
== Domain Entities

Most domain objects that the end-user interacts with are likely to be _domain entities_, such as `Customer`, `Order`, `Product` and so on.
These are persistent objects and which are mapped to a database (usually relational), using JDO/DataNucleus annotations.

Some domain entities are really aggregates, a combination of multiple objects.
A commonly cited example of this is an `Order`, which really consists of both a root `Order` entity and a collection of ``OrderItem``s.
From the end-users' perspective, when they talk of "order" they almost always mean the aggregate rather than just the `Order` root entity.

Eric Evans' link:http://books.google.com/books/about/Domain_Driven_Design.html?id=hHBf4YxMnWMC[Domain Driven Design] has a lot to say about aggregate roots and their responsibilities: in particular that it is the responsibility of the aggregate root to maintain the invariants of its component pieces, and that roots may only reference other roots.
There's good logic here: requiring only root-to-root relationships reduces the number of moving parts that the developer has to think about.

On the other hand, this constraint can substantially complicate matters when mapping domain layer to the persistence layer.
DDD tends to de-emphasise such matters: it aims to be completely agnostic about the persistence layer, with the responsibilities for managing relationships moved (pretty much by definition) into the domain layer.

As a framework Apache Isis is less dogmatic about such things.
Generally the domain objects are mapped to a relational database and so we can lean on the referential integrity capabilities of the persistence layer to maintain referential invariants.
Said another way: we don't tend to require that only roots can maintain roots: we don't see anything wrong in an `InvoiceItem` referencing an `OrderItem`, for example.

Nonetheless the concepts of "aggregate" and "aggregate root" are worth holding onto.
You'll probably find yourself defining a repository service (discussed in more detail below) for each aggregate root: for example `Order` will have a corresponding `OrderRepository` service.
Similarly, you may also have a factory service, for example `OrderFactory`.
However, you are less likely to have a repository service for the parts of an aggregate root: the role of retrieving ``OrderItem``s should fall to the `Order` root (typically by way of lazy loading of an "items" collection) rather than through an `OrderItemRepository` service.
This isn't a hard-n-fast rule, but it is a good rule of thumb.

[TIP]
====
Details on how to actually write a domain entity (the programming model for domain entities) is
xref:userguide:fun:domain-entities-and-services.adoc#domain-entities[here].
====

[#domain-services]
== Domain Services

_Domain services_ are (usually) singleton stateless services that provide additional functionality.
Domain services consist of a set of logically grouped actions, and as such follow the same conventions as for entities.
However, a service cannot have (persisted) properties, nor can it have (persisted) collections.

A very common type of domain service is a repository, that is used to look up existing instances of a domain entity.
For example, for the `Customer` entity there may be a `CustomerRepository`, while for `Order` entity there may be an `OrderRepository`.

Similarly, entities might also have a corresponding factory service: a `CustomerFactory` or an `OrderFactory`; Evans' link:http://books.google.com/books/about/Domain_Driven_Design.html?id=hHBf4YxMnWMC[Domain Driven Design], draws a clear distinction between a factory (that creates object) and a repository (that is used to find existing objecpts).

On the other hand, from an end-users' perspective the act of finding an existing object vs creating a new one are quite closely related.
For this reason, in Apache Isis it's therefore quite common to have a single domain service that acts as both a factory and a repository (and is usually called just a "repository").

The behaviour of these services is rendered in various ways, though the most obvious is as the menu actions on the top-level menu bars in the xref:vw:ROOT:about.adoc[Web UI (Wicket viewer)]'s UI.

Domain services can also be used for a number of other purposes:

* to provide additional non-UI functionality; an example being to perform an address geocoding lookup against the google-maps API, or to perform some calculation, or attach a barcode, send an email etc

* to act as a subscribers to the event bus, potentially influencing events fired by some other module (a key technique for decoupling large applications)
+
This is discussed in more detail below, in the section on xref:userguide:fun:overview.adoc#events[events].

* to implement an link:https://en.wikipedia.org/wiki/Service_provider_interface[SPI] of the Apache Isis framework, most notably cross-cutting concerns such as security, command profiling, auditing and publishing.

Domain objects of any type (entities, other services, view models, mixins) can also delegate to domain services; domain services are automatically injected into every other domain object.
This injection of domain services into entities is significant: it allows business logic to be implemented in the domain entities, rather than have it "leach away" into supporting service layers.
Said another way: it is the means by which Apache Isis helps you avoid the anaemic domain model anti-pattern.

Domain services are instantiated once and once only by the framework, and are used to centralize any domain logic that does not logically belong in a domain entity or value.

[TIP]
====
Details on how to actually write a domain service (the programming model for domain services) is
xref:userguide:fun:domain-entities-and-services.adoc#domain-services[here].
====

=== Hexagonal Architecture

It's worth extending the xref:userguide:fun:concepts-patterns.adoc#hexagonal-architecture[Hexagonal Architecture] to show where domain services fit in:

.The hexagonal architecture with API and SPI implementations
image::core-concepts/philosophy/hexagonal-architecture-addons.png[width="700px"]

The xref:extensions:ROOT:about.adoc[extensions] catalog provide SPI implementations of the common cross-cutting concerns.
You can also write your own domain services as well, for example to interface with some external CMS system, say.

[#view-models]
== View Models

View models are similar to entities in that (unlike domain services) there can be many instances of any given type.
End users interact with view models in the same way as a domain entity, indeed they are unlikely to distinguish one from the other.

However, whereas domain entities are mapped to a datastore, view models are not.
Instead they are recreated dynamically by serializing their state, ultimately into the URL itself (meaning their state it is in effect implicitly managed by the client browser).
You will notice that the URL for view models (as shown in xref:vw:ROOT:about.adoc[Web UI (Wicket viewer)] or xref:vro:ROOT:about.adoc[RestfulObjects viewer]) tends to be quite long.

This capability opens up a number of more advanced use cases:

* In the same way that an (RDBMS) database view can aggregate and abstract from multiple underlying database tables, a view model sits on top of one or many underlying entities.

* A view model could also be used as a proxy for some externally managed entity, accessed over a web service or REST API; it could even be a representation of state held in-memory (such as user preferences, for example).

* view models can also be used to support a particular use case.
An example that comes to mind is to expose a list of scanned PDFs to be processed as an "intray", showing the list of PDFs on one side of the page, and the current PDF being viewed on the other.
Such view models are part of the application layer, not part of the domain layer (where entities live).

We explore these use cases in more detail below.

[TIP]
====
Details on how to actually write a view model (the programming model for view models) can be found xref:userguide:fun:view-models.adoc[here].
====

=== Externally-managed entities

Sometimes the entities that make up your application are persisted not in the local database but reside in some other system, for example accessible only through a SOAP web service.
Logically that data might still be considered a domain entity and we might want to associate behaviour with it, however it cannot be modelled as a domain entity if only because JDO/DataNucleus doesn't know about the entity nor how to retrieve or update it.

There are a couple of ways around this: we could either replicate the data somehow from the external system into the Isis-managed database (in which case it is once again just another domain entity), or we could set up a stub/proxy for the externally managed entity.
This proxy would hold the reference to the externally-managed domain entity (eg an external id), as well as the "smarts" to know how to interact with that entity (by making SOAP web service calls etc).

The stub/proxy is a type of view model: a view -- if you like -- onto the domain entity managed by the external system.

=== In-memory entities

As a variation on the above, sometimes there are domain objects that are, conceptually at least entities, but whose state is not actually persisted anywhere, merely held in-memory (eg in a hash).

A simple example is read-only configuration data that is read from a config file (eg log4j appender definitions) but thereafter is presented in the UI just like any other entity.

=== Application-layer view models

Domain entities (whether locally persisted or managed externally) are the bread-and-butter of Apache Isis applications: the focus after all, should be on the business domain concepts and ensuring that they are solid.
Generally those domain entities will make sense to the business domain experts: they form the _ubiquitous language_ of the domain.
These domain entities are part of the domain layer.

When developing an Apache Isis application you will most likely start off with the persistent domain entities: `Customer`, `Order`, `Product`, and so on.
For some applications this may well suffice.

That said, it may not always be practical to expect end-users of the application to interact solely with those domain entities.
If the application needs to integrate with other systems, or if the application needs to support reasonably complex business processes, then you may need to look beyond just domain entities; view models are the tool of choice.

One such use case for view models is to help co-ordinate complex business processes; for example to perform a quarterly invoicing run, or to upload annual interest rates from an Excel spreadsheet, or prepare payment batches from incoming invoices, to be uploaded to an external payment system.
In these cases the view model managing the business process might have some state of its own, but in most cases that state does not need to be persisted between user sessions.
Many of the actions will be queries but in some cases such view model actions might also modify state of underlying domain entities.
Either way, ultimately these actions just delegate down to the domain-layer.

.Desire Lines
****
One way to think of application view models is that they model the "desire line": the commonly-trod path that end-users must follow to get from point A to point B as quickly as possible.

To explain: there are link:http://ask.metafilter.com/62599/Where-the-sidewalk-ends[documented] link:https://sivers.org/walkways[examples] link:http://www.softpanorama.org/People/Wall/larry_wall_articles_and_interviews.shtml[that] architects of university campus will only add in paths some while after the campus buildings are complete: let the pedestrians figure out the routes they want to take.
One name for this idea is "desire lines".

What that means is you should add view models _after_ having built up the domain layer, rather than before.
These view models pave that commonly-trod path, automating the steps that the end-user would otherwise have to do by hand.

However, you _shouldn't_ try to build out a domain layer that could support every conceivable use case before starting to think about view models.
Instead, iterate.
Identify the use case/story/end-user objective that will deliver value to the business.
Build out the minimum domain entities to support that use case.
Then, introduce view models to simplify high-volume end-user interactions with the system (perhaps automating several related use cases together).
****

Another common requirement is to show a dashboard of the most significant data in the system to a user, often pulling in and aggregating information from multiple points of the app.
Obtaining this information by hand (by querying the respective services/repositories) would be tedious and slow; far better to have a dashboard do the job for the end user.

A dashboard object is a model of the most relevant state to the end-user, in other words it is (quite literally) a view model.
It is not a persisted entity, instead it belongs to the application layer.

=== DTOs

DTOs (data transfer objects) are simple classes that (according to link:https://en.wikipedia.org/wiki/Data_transfer_object[wikipedia]) "carry data between processes".

If those two processes are parts of the same overall application (the same team builds and deploys both server and client) then there's generally no need to define a DTO; just access the entities using Apache Isis' xref:vro:ROOT:about.adoc[RestfulObjects viewer].

On the other hand, if the client consuming the DTO is a different application -- by which we mean developed/deployed by a different (possible third-party) team -- then the DTOs act as a formal contract between the provider and the consumer.
In such cases, exposing domain entities over xref:vro:ROOT:about.adoc[RestfulObjects] would be "A Bad Thing"(TM) because the consumer would in effect have access to implementation details that could then not be easily changed by the producer.
There's plenty of discussion on this topic (eg link:https://stackoverflow.com/questions/36174516/rest-api-dtos-or-not[here] and link:https://juristr.com/blog/2012/10/lessions-learned-dont-expose-ef-entities-to-the-client-directly/[here]).
Almost all of these recommend exposing only DTOs (which is to say view models), not domain entities, in REST APIs.

To support this use case, a view model can be defined such that it can act as a DTO.
This is done by annotating the class using JAXB annotations; this allows the consumer to obtain the DTO in XML format along with a corresponding XSD schema describing the structure of that XML.


These DTOs are still usable as "regular" view models; they will render in the xref:vw:ROOT:about.adoc[Web UI (Wicket viewer)] just like any other.
In fact (as the xref:userguide:fun:view-models.adoc#jaxb[programming model] section below makes clear), these JAXB-annotated view models are in many regards the most powerful of all the alternative ways of writing view models.

It's also worth noting that it is also possible to download the XML (or XSD) straight from the UI, useful during development.
The view model simply needs to implement the xref:refguide:applib:index/mixins/dto/Dto.adoc[Dto] marker interface; the framework has xref:refguide:applib-classes:mixees-and-mixins.adoc#Dto[mixins] that contribute the download actions to the view model.

=== For REST Clients

The xref:vro:ROOT:about.adoc[Restful Objects] viewer automatically provides a REST API for both domain entities.
Or, you can use it to only expose view models, taking care to map the state of the domain entity/ies into a view model.
The question to consider is whether the REST API is a public API or an internal private API:

* If it's a public API, which is to say that there are third-party clients out over which you have no control, then view models are the way to go.
+
In this case view models provide an isolation layer which allow you to modify the structure of the underlying domain entities without breaking this API.

* If it's a private API, which is to say that the only clients of the REST API are under your control, then view models are an unnecessary overhead.
+
In this case, just expose domain entities directly.

The caveat to the "private API" option is that private APIs have a habit of becoming public APIs.
Even if the REST API is only exposed within your organisation's intranet, other teams may "discover" your REST API and start writing applications that consume it.
If that REST API is exposing domain entities, you could easily break those other teams' clients if you refactor.

[NOTE]
====
The link:https://projects.spring.io/spring-data-rest/[Spring Data REST] subproject has a similar capability of being able to expose domain entities as REST resources.
This link:https://stackoverflow.com/questions/38874746/is-it-problematic-that-spring-data-rest-exposes-entities-via-rest-resources-with[SO question], which debates the pros-and-cons, is also worth a read.
====

If your REST API is intended to be public (or you can't be sure that it will remain private), then exposing view models will entail a lot of marshalling of state from domain entities into view models.
There are numerous open source tools that can help with that, for example link:http://modelmapper.org/[Model Mapper], link:http://dozer.sourceforge.net/[Dozer] and link:https://github.com/orika-mapper/orika[Orika].

Or, rather than marshalling state, the view model could hold a reference to the underlying domain entity/ies and dynamically read from it (ie, all the view model's properties are derived from the entity's).

A third option is to define an RDBMS view, and then map a "non-durable" entity to that view.
The RDBMS view then becomes the public API that must be preserved.
ORMs such as DataNucleus link:http://www.datanucleus.org:15080/products/accessplatform_5_1/jdo/mapping.html#schema_rdbms_views[support this].

[#mixins]
== Mixins

The final type of domain object is the *mixin*.
These are similar to traits or extension methods in other programming languages.
A mixin object allows one class to contribute behaviour - actions, (derived) properties and (derived) collections - to another domain object, either a domain entity or view model.
Or rather, the mixin _appears_ to contribute the behaviour/state in the UI; the underlying domain class being "decorated" does not know this is happening.

This is therefore a key technique to allow the app to stay decoupled, so that it doesn't degrade into the proverbial link:http://www.laputan.org/mud/mud.html#BigBallOfMud["big ball of mud"].
There's a lot more discussion on this topic in xref:overview.adoc#modules[modules], below.


Mixins are also a convenient mechanism for grouping functionality even for a concrete type, helping to rationalize about the dependency between the data and the behaviour.
Each mixin is in effect a single behavioural "responsibility" of the domain object.

In fact, we find mixins nicely balance inside-out vs outside-in ways of thinking about a system:

* inside-out tends to focus on the structure, the nouns that make up the domain.

* outside-in tends to focus on the behaviour, that is the functionality that the system provides to automate the business processes; the verbs, in other words.

So, while Apache Isis allows you to put behaviour onto the underlying domain entities, it can often be better to treat the domain entities as immutable.
Instead, use mixins to implement behaviour.
When using an agile development methodology, it's common for a user story to correspond to a new mixin.

There are also practical reasons for moving behaviour out of entities even within the same module, because structuring your application this way helps support hot-reloading of Java classes (so that you can modify and recompile your application without having to restart it).
This can provide substantial productivity gains.

The Hotspot JVM has limited support for hot reloading; generally you can change method implementations but you cannot introduce new methods.
However, the link:https://dcevm.github.io/[DCEVM] open source project will patch the JVM to support much more complete hot reloading support.
There are also commercial products such as JRebel.

[TIP]
====
Details on how to actually write a mixin (the programming model for mixins) is
xref:userguide:fun:mixins.adoc[here].
====

.DCI Architecture
****
Mixins are an implementation of the link:http://www.artima.com/articles/dci_vision.html[DCI architecture] architecture, as formulated and described by link:https://en.wikipedia.org/wiki/Trygve_Reenskaug[Trygve Reenskaug] and link:https://en.wikipedia.org/wiki/Jim_Coplien[Jim Coplien].
Reenskaug was the inventor of the MVC pattern (and also the external examiner for Richard Pawson's link:../../../../../ug/fun/_attachments/core-concepts/Pawson-Naked-Objects-thesis.pdf[PhD thesis]), while Coplien has a long history in object-orientation, C++ and patterns.

DCI stands for Data-Context-Interaction and is presented as an evolution of object-oriented programming, but one where behaviour is bound to objects dynamically rather than statically in some context or other.
The mixin pattern is Apache Isis' straightforward take on the same basic concept.
****


