blob: c7c38ed737ef9e0076e197c61164d6a6e0ab2985 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Overview :: Apache Isis</title>
<link rel="canonical" href="https://isis.apache.org/userguide/2.0.0-M5/fun/overview.html">
<meta name="generator" content="Antora 2.3.4">
<link rel="stylesheet" href="../../../_/css/site.css">
<link rel="stylesheet" href="../../../_/css/site-custom.css">
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,700,700i|Raleway:300,400,500,700,800|Montserrat:300,400,700" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.css"/>
<link rel="home" href="https://isis.apache.org" title="Apache Isis">
<link rel="next" href="domain-entities-and-services.html" title="Domain Entities &amp;amp; Services">
<link rel="prev" href="concepts-patterns.html" title="Concepts &amp;amp; Patterns">
</head>
<body class="article">
<header class="header">
<nav class="navbar">
<div class="navbar-brand">
<a class="navbar-item" href="https://isis.apache.org">
<span class="icon">
<img src="../../../_/img/isis-logo-48x48.png"></img>
</span>
<span>Apache Isis</span>
</a>
<button class="navbar-burger" data-target="topbar-nav">
<span></span>
<span></span>
<span></span>
</button>
</div>
<div id="topbar-nav" class="navbar-menu">
<a class="navbar-end">
<div class="navbar-item hide-for-print">
<span>
<input id="algolia-search-input" placeholder="Search"></span>
</span>
</div>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#">Quick Start</a>
<div class="navbar-dropdown">
<span class="navbar-item navbar-heading">Starter Apps</span>
<a class="navbar-item" href="../../../docs/2.0.0-M5/starters/helloworld.html">Hello World</a>
<a class="navbar-item" href="../../../docs/2.0.0-M5/starters/simpleapp.html">Simple App</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Demos &amp; Tutorials</span>
<a class="navbar-item" href="../../../docs/2.0.0-M5/demo/about.html">Demo App</a>
<a class="navbar-item" href="https://danhaywood.gitlab.io/isis-petclinic-tutorial-docs/petclinic/1.16.2/intro.html">Petclinic (tutorial)</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Resources</span>
<a class="navbar-item" href="../../../docs/2.0.0-M5/resources/cheatsheet.html">Cheatsheet</a>
<a class="navbar-item" href="../../../docs/2.0.0-M5/resources/icons.html">Icons</a>
</div>
</div>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#">Guides</a>
<div class="navbar-dropdown">
<span class="navbar-item navbar-heading">Development</span>
<a class="navbar-item" href="../../../setupguide/2.0.0-M5/about.html">Setup Guide</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Core</span>
<a class="navbar-item" href="../../../userguide/2.0.0-M5/about.html">User Guide</a>
<a class="navbar-item" href="../../../refguide/2.0.0-M5/about.html">Reference Guide</a>
<a class="navbar-item" href="../../../testing/2.0.0-M5/about.html">Testing Guide</a>
</div>
</div>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#">Libraries</a>
<div class="navbar-dropdown">
<span class="navbar-item navbar-heading">For Use in Apps</span>
<a class="navbar-item" href="../../../subdomains/2.0.0-M5/about.html">Subdomain Libraries</a>
<a class="navbar-item" href="../../../valuetypes/2.0.0-M5/about.html">Value Types</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Integrate between Apps</span>
<a class="navbar-item" href="../../../mappings/2.0.0-M5/about.html">Bounded Context Mapping Libraries</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Other</span>
<a class="navbar-item" href="../../../incubator/2.0.0-M5/about.html">Incubator</a>
<a class="navbar-item" href="../../../legacy/2.0.0-M5/about.html">Legacy</a>
</div>
</div>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#">Components</a>
<div class="navbar-dropdown">
<span class="navbar-item navbar-heading">Viewers</span>
<a class="navbar-item" href="../../../vw/2.0.0-M5/about.html">Web UI (Wicket)</a>
<a class="navbar-item" href="../../../vro/2.0.0-M5/about.html">REST API (Restful Objects)</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Security</span>
<a class="navbar-item" href="../../../security/2.0.0-M5/about.html">Security Guide</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Persistence</span>
<a class="navbar-item" href="../../../pjpa/2.0.0-M5/about.html">JPA (EclipseLink)</a>
<a class="navbar-item" href="../../../pjdo/2.0.0-M5/about.html">JDO (DataNucleus)</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Extensions</span>
<a class="navbar-item" href="../../../extensions/2.0.0-M5/about.html">Extensions Catalog</a>
</div>
</div>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#">Support</a>
<div class="navbar-dropdown">
<span class="navbar-item navbar-heading">Contact</span>
<a class="navbar-item" href="../../../docs/2.0.0-M5/support/slack-channel.html">Slack</a>
<a class="navbar-item" href="../../../docs/2.0.0-M5/support/mailing-list.html">Mailing Lists</a>
<a class="navbar-item" href="https://issues.apache.org/jira/browse/ISIS">JIRA</a>
<a class="navbar-item" href="https://stackoverflow.com/questions/tagged/isis">Stack Overflow</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Releases</span>
<a class="navbar-item" href="../../../docs/2.0.0-M5/downloads/how-to.html">Downloads</a>
<a class="navbar-item" href="../../../relnotes/2.0.0-M5/about.html">Release Notes</a>
<a class="navbar-item" href="../../../docs/2.0.0-M5/archive/1-x.html">Archive (1.x)</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Framework</span>
<a class="navbar-item" href="../../../conguide/2.0.0-M5/about.html">Contributors' Guide</a>
<a class="navbar-item" href="../../../comguide/2.0.0-M5/about.html">Committers' Guide</a>
<a class="navbar-item" href="../../../core/2.0.0-M5/about.html">Core Design</a>
</div>
</div>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#">ASF</a>
<div class="navbar-dropdown">
<a class="navbar-item" href="http://www.apache.org/">Apache Homepage</a>
<a class="navbar-item" href="https://www.apache.org/events/current-event">Events</a>
<a class="navbar-item" href="https://www.apache.org/licenses/">Licenses</a>
<a class="navbar-item" href="https://www.apache.org/security/">Security</a>
<a class="navbar-item" href="https://www.apache.org/foundation/sponsorship.html">Sponsorship</a>
<a class="navbar-item" href="https://www.apache.org/foundation/thanks.html">Thanks</a>
<hr class="navbar-divider"/>
<a class="navbar-item" href="https://whimsy.apache.org/board/minutes/Isis.html">PMC board minutes</a>
</div>
</div>
<a class="navbar-item" href="../../../docs/2.0.0-M5/about.html">
<span class="icon">
<img src="../../../_/img/home.png"></img>
</span>
</a>
</div>
</div>
</nav>
</header>
<div class="body ">
<div class="nav-container" data-component="userguide" data-version="2.0.0-M5">
<aside class="nav">
<div class="panels">
<div class="nav-panel-pagination">
<a class="page-previous" rel="prev" href="concepts-patterns.html" title="Concepts &amp;amp; Patterns"><span></span></a>
<a class="page-next" rel="next"
href="domain-entities-and-services.html" title="Domain Entities &amp;amp; Services"><span></span></a>
<!--
page.parent doesn't seem to be set...
<a class="page-parent disabled" rel="prev" href="" title="Concepts &amp;amp; Patterns"><span></span></a>
-->
</div>
<div class="nav-panel-menu is-active" data-panel="menu">
<nav class="nav-menu">
<h3 class="title"><a href="../about.html">User Guide</a></h3>
<ul class="nav-list">
<li class="nav-item" data-depth="0">
<ul class="nav-list">
<li class="nav-item" data-depth="1">
<a class="nav-link" href="concepts-patterns.html">Concepts &amp; Patterns</a>
</li>
<li class="nav-item is-current-page" data-depth="1">
<a class="nav-link" href="overview.html">Overview</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="domain-entities-and-services.html">Domain Entities &amp; Services</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="object-members.html">Properties, Collections &amp; Actions</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="ui.html">UI Layout &amp; Hints</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="business-rules.html">Business Rules</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="drop-downs-and-defaults.html">Drop downs and Defaults</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="meta-annotations.html">Meta-annotations</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="view-models.html">View Models</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="mixins.html">Mixins</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="modules.html">Modules</a>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../btb/about.html">Beyond the Basics</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../btb/i18n.html">i18n</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../btb/headless-access.html">Headless Access</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../btb/hints-and-tips.html">Hints-n-Tips</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../btb/programming-model.html">Programming Model</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<span class="nav-text">Extensions</span>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../command-log/about.html">Command Log</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../command-replay/about.html">Command Replay</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../flyway/about.html">Flyway</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../model-annotation/about.html">Model Annotation</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../quartz/about.html">Quartz</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</div>
<div class="nav-panel-explore" data-panel="explore">
<div class="context">
<span class="title">User Guide</span>
<span class="version">2.0.0-M5</span>
</div>
<ul class="components">
<li class="component">
<span class="title"> </span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../docs/2.0.0-M5/about.html">2.0.0-M5</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">BC Mapping Libraries</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../mappings/2.0.0-M5/about.html">2.0.0-M5</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Committers' Guide</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../comguide/2.0.0-M5/about.html">2.0.0-M5</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Contributors' Guide</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../conguide/2.0.0-M5/about.html">2.0.0-M5</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Design Docs</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../core/2.0.0-M5/about.html">2.0.0-M5</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Extensions Catalog</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../extensions/2.0.0-M5/about.html">2.0.0-M5</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Incubator Catalog</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../incubator/2.0.0-M5/about.html">2.0.0-M5</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">JDO/DataNucleus</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../pjdo/2.0.0-M5/about.html">2.0.0-M5</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">JPA</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../pjpa/2.0.0-M5/about.html">2.0.0-M5</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Legacy Catalog</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../legacy/2.0.0-M5/about.html">2.0.0-M5</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Reference Guide</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../refguide/2.0.0-M5/about.html">2.0.0-M5</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Release Notes</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../relnotes/2.0.0-M5/about.html">2.0.0-M5</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">REST API (Restful Objects Viewer)</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../vro/2.0.0-M5/about.html">2.0.0-M5</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Security Guide</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../security/2.0.0-M5/about.html">2.0.0-M5</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Setup Guide</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../setupguide/2.0.0-M5/about.html">2.0.0-M5</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Subdomains Catalog</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../subdomains/2.0.0-M5/about.html">2.0.0-M5</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Testing Guide</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../testing/2.0.0-M5/about.html">2.0.0-M5</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Tooling</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../tooling/2.0.0-M5/about.html">2.0.0-M5</a>
</li>
</ul>
</li>
<li class="component is-current">
<span class="title">User Guide</span>
<ul class="versions">
<li class="version is-current is-latest">
<a href="../about.html">2.0.0-M5</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Value Types Catalog</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../valuetypes/2.0.0-M5/about.html">2.0.0-M5</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Web UI (Wicket Viewer)</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../vw/2.0.0-M5/about.html">2.0.0-M5</a>
</li>
</ul>
</li>
</ul>
</div>
</div>
</aside>
</div>
<main role="main">
<div class="toolbar" role="navigation">
<button class="nav-toggle"></button>
<a href="../../../docs/2.0.0-M5/about.html" class="home-link"></a>
<nav class="breadcrumbs" aria-label="breadcrumbs">
<ul>
<li><a href="../about.html">User Guide</a></li>
<li><a href="overview.html">Overview</a></li>
</ul>
</nav>
<div class="edit-this-page"><a href="https://github.com/apache/isis/edit/2.0.0-M5/antora/components/userguide/modules/fun/pages/overview.adoc">Edit</a></div>
</div>
<article class="doc">
<a name="section-top"></a>
<h1 class="page">Overview</h1>
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>In this section we run through the main building blocks that make up an Apache Isis application.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="type-of-domain-objects"><a class="anchor" href="#type-of-domain-objects"></a>Type of Domain Objects</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Apache Isis supports recognises four main types of domain classes:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>domain entities</strong> - domain objects persisted to the database the ORM (eg JDO/DataNucleus); for example <code>Customer</code></p>
</li>
<li>
<p><strong>domain services</strong> - generally singletons, automatically injected, and providing various functionality; for example <code>CustomerRepository</code></p>
</li>
<li>
<p><strong>view models</strong> - domain objects that are a projection of some state held by the database, in support a particular use case; for example <code>CustomerDashboard</code> (to pull together commonly accessed information about a customer).</p>
</li>
<li>
<p><strong>mixins</strong> - 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.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>From the end-user&#8217;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.</p>
</div>
<div class="paragraph">
<p>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 <code>@DomainObject</code> and <code>@DomainService</code>.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>The framework also defines supplementary annotations, notably <a href="../../../refguide/2.0.0-M5/applib/index/annotation/DomainObjectLayout.html" class="page">@DomainObjectLayout</a> and <a href="../../../refguide/2.0.0-M5/applib/index/annotation/DomainServiceLayout.html" class="page">@DomainServiceLayout</a>.
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 <a href="ui.html#object-layout" class="page">.layout.xml</a> file.</p>
</div>
<div class="sect2">
<h3 id="domain-entities"><a class="anchor" href="#domain-entities"></a>Domain Entities</h3>
<div class="paragraph">
<p>Most domain objects that the end-user interacts with are likely to be <em>domain entities</em>, such as <code>Customer</code>, <code>Order</code>, <code>Product</code> and so on.
These are persistent objects and which are mapped to a database (usually relational), using JDO/DataNucleus annotations.</p>
</div>
<div class="paragraph">
<p>Some domain entities are really aggregates, a combination of multiple objects.
A commonly cited example of this is an <code>Order</code>, which really consists of both a root <code>Order</code> entity and a collection of <code>OrderItem</code>s.
From the end-users' perspective, when they talk of "order" they almost always mean the aggregate rather than just the <code>Order</code> root entity.</p>
</div>
<div class="paragraph">
<p>Eric Evans' <a href="http://books.google.com/books/about/Domain_Driven_Design.html?id=hHBf4YxMnWMC">Domain Driven Design</a> 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&#8217;s good logic here: requiring only root-to-root relationships reduces the number of moving parts that the developer has to think about.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>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&#8217;t tend to require that only roots can maintain roots: we don&#8217;t see anything wrong in an <code>InvoiceItem</code> referencing an <code>OrderItem</code>, for example.</p>
</div>
<div class="paragraph">
<p>Nonetheless the concepts of "aggregate" and "aggregate root" are worth holding onto.
You&#8217;ll probably find yourself defining a repository service (discussed in more detail below) for each aggregate root: for example <code>Order</code> will have a corresponding <code>OrderRepository</code> service.
Similarly, you may also have a factory service, for example <code>OrderFactory</code>.
However, you are less likely to have a repository service for the parts of an aggregate root: the role of retrieving <code>OrderItem</code>s should fall to the <code>Order</code> root (typically by way of lazy loading of an "items" collection) rather than through an <code>OrderItemRepository</code> service.
This isn&#8217;t a hard-n-fast rule, but it is a good rule of thumb.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Details on how to actually write a domain entity (the programming model for domain entities) is
<a href="domain-entities-and-services.html#domain-entities" class="page">here</a>.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="domain-services"><a class="anchor" href="#domain-services"></a>Domain Services</h3>
<div class="paragraph">
<p><em>Domain services</em> 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.</p>
</div>
<div class="paragraph">
<p>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 <code>Customer</code> entity there may be a <code>CustomerRepository</code>, while for <code>Order</code> entity there may be an <code>OrderRepository</code>.</p>
</div>
<div class="paragraph">
<p>Similarly, entities might also have a corresponding factory service: a <code>CustomerFactory</code> or an <code>OrderFactory</code>; Evans' <a href="http://books.google.com/books/about/Domain_Driven_Design.html?id=hHBf4YxMnWMC">Domain Driven Design</a>, draws a clear distinction between a factory (that creates object) and a repository (that is used to find existing objecpts).</p>
</div>
<div class="paragraph">
<p>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&#8217;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").</p>
</div>
<div class="paragraph">
<p>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 <a href="../../../vw/2.0.0-M5/about.html" class="page">Web UI (Wicket viewer)</a>'s UI.</p>
</div>
<div class="paragraph">
<p>Domain services can also be used for a number of other purposes:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>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</p>
</li>
<li>
<p>to act as a subscribers to the event bus, potentially influencing events fired by some other module (a key technique for decoupling large applications)</p>
<div class="paragraph">
<p>This is discussed in more detail below, in the section on <a href="#events">events</a>.</p>
</div>
</li>
<li>
<p>to implement an <a href="https://en.wikipedia.org/wiki/Service_provider_interface">SPI</a> of the Apache Isis framework, most notably cross-cutting concerns such as security, command profiling, auditing and publishing.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Details on how to actually write a domain service (the programming model for domain services) is
<a href="domain-entities-and-services.html#domain-services" class="page">here</a>.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="sect3">
<h4 id="hexagonal-architecture"><a class="anchor" href="#hexagonal-architecture"></a>Hexagonal Architecture</h4>
<div class="paragraph">
<p>It&#8217;s worth extending the <a href="concepts-patterns.html#hexagonal-architecture" class="page">Hexagonal Architecture</a> to show where domain services fit in:</p>
</div>
<div class="imageblock">
<div class="content">
<img src="_images/core-concepts/philosophy/hexagonal-architecture-addons.png" alt="hexagonal architecture addons" width="700px">
</div>
<div class="title">Figure 1. The hexagonal architecture with API and SPI implementations</div>
</div>
<div class="paragraph">
<p>The <a href="../../../extensions/2.0.0-M5/about.html" class="page">extensions</a> 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.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="view-models"><a class="anchor" href="#view-models"></a>View Models</h3>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>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 <a href="../../../vw/2.0.0-M5/about.html" class="page">Web UI (Wicket viewer)</a> or <a href="../../../vro/2.0.0-M5/about.html" class="page">RestfulObjects viewer</a>) tends to be quite long.</p>
</div>
<div class="paragraph">
<p>This capability opens up a number of more advanced use cases:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>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.</p>
</li>
<li>
<p>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).</p>
</li>
<li>
<p>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).</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>We explore these use cases in more detail below.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Details on how to actually write a view model (the programming model for view models) can be found <a href="view-models.html" class="page">here</a>.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="sect3">
<h4 id="externally-managed-entities"><a class="anchor" href="#externally-managed-entities"></a>Externally-managed entities</h4>
<div class="paragraph">
<p>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&#8217;t know about the entity nor how to retrieve or update it.</p>
</div>
<div class="paragraph">
<p>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).</p>
</div>
<div class="paragraph">
<p>The stub/proxy is a type of view model: a view&#8201;&#8212;&#8201;if you like&#8201;&#8212;&#8201;onto the domain entity managed by the external system.</p>
</div>
</div>
<div class="sect3">
<h4 id="in-memory-entities"><a class="anchor" href="#in-memory-entities"></a>In-memory entities</h4>
<div class="paragraph">
<p>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).</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
</div>
<div class="sect3">
<h4 id="application-layer-view-models"><a class="anchor" href="#application-layer-view-models"></a>Application-layer view models</h4>
<div class="paragraph">
<p>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 <em>ubiquitous language</em> of the domain.
These domain entities are part of the domain layer.</p>
</div>
<div class="paragraph">
<p>When developing an Apache Isis application you will most likely start off with the persistent domain entities: <code>Customer</code>, <code>Order</code>, <code>Product</code>, and so on.
For some applications this may well suffice.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="sidebarblock">
<div class="content">
<div class="title">Desire Lines</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>To explain: there are <a href="http://ask.metafilter.com/62599/Where-the-sidewalk-ends">documented</a> <a href="https://sivers.org/walkways">examples</a> <a href="http://www.softpanorama.org/People/Wall/larry_wall_articles_and_interviews.shtml">that</a> 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".</p>
</div>
<div class="paragraph">
<p>What that means is you should add view models <em>after</em> 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.</p>
</div>
<div class="paragraph">
<p>However, you <em>shouldn&#8217;t</em> 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).</p>
</div>
</div>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
</div>
<div class="sect3">
<h4 id="dtos"><a class="anchor" href="#dtos"></a>DTOs</h4>
<div class="paragraph">
<p>DTOs (data transfer objects) are simple classes that (according to <a href="https://en.wikipedia.org/wiki/Data_transfer_object">wikipedia</a>) "carry data between processes".</p>
</div>
<div class="paragraph">
<p>If those two processes are parts of the same overall application (the same team builds and deploys both server and client) then there&#8217;s generally no need to define a DTO; just access the entities using Apache Isis' <a href="../../../vro/2.0.0-M5/about.html" class="page">RestfulObjects viewer</a>.</p>
</div>
<div class="paragraph">
<p>On the other hand, if the client consuming the DTO is a different application&#8201;&#8212;&#8201;by which we mean developed/deployed by a different (possible third-party) team&#8201;&#8212;&#8201;then the DTOs act as a formal contract between the provider and the consumer.
In such cases, exposing domain entities over <a href="../../../vro/2.0.0-M5/about.html" class="page">RestfulObjects</a> would be "A Bad Thing"&#8482; because the consumer would in effect have access to implementation details that could then not be easily changed by the producer.
There&#8217;s plenty of discussion on this topic (eg <a href="https://stackoverflow.com/questions/36174516/rest-api-dtos-or-not">here</a> and <a href="https://juristr.com/blog/2012/10/lessions-learned-dont-expose-ef-entities-to-the-client-directly/">here</a>).
Almost all of these recommend exposing only DTOs (which is to say view models), not domain entities, in REST APIs.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>These DTOs are still usable as "regular" view models; they will render in the <a href="../../../vw/2.0.0-M5/about.html" class="page">Web UI (Wicket viewer)</a> just like any other.
In fact (as the <a href="view-models.html#jaxb" class="page">programming model</a> 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.</p>
</div>
<div class="paragraph">
<p>It&#8217;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 <a href="../../../refguide/2.0.0-M5/applib/index/mixins/dto/Dto.html" class="page">Dto</a> marker interface; the framework has <a href="#refguide:applib-classes:mixins.adoc#Dto" class="page unresolved">mixins</a> that contribute the download actions to the view model.</p>
</div>
</div>
<div class="sect3">
<h4 id="for-rest-clients"><a class="anchor" href="#for-rest-clients"></a>For REST Clients</h4>
<div class="paragraph">
<p>The <a href="../../../vro/2.0.0-M5/about.html" class="page">Restful Objects</a> 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:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>If it&#8217;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.</p>
<div class="paragraph">
<p>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.</p>
</div>
</li>
<li>
<p>If it&#8217;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.</p>
<div class="paragraph">
<p>In this case, just expose domain entities directly.</p>
</div>
</li>
</ul>
</div>
<div class="paragraph">
<p>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&#8217;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.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>The <a href="https://projects.spring.io/spring-data-rest/">Spring Data REST</a> subproject has a similar capability of being able to expose domain entities as REST resources.
This <a href="https://stackoverflow.com/questions/38874746/is-it-problematic-that-spring-data-rest-exposes-entities-via-rest-resources-with">SO question</a>, which debates the pros-and-cons, is also worth a read.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>If your REST API is intended to be public (or you can&#8217;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 <a href="http://modelmapper.org/">Model Mapper</a>, <a href="http://dozer.sourceforge.net/">Dozer</a> and <a href="https://github.com/orika-mapper/orika">Orika</a>.</p>
</div>
<div class="paragraph">
<p>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&#8217;s properties are derived from the entity&#8217;s).</p>
</div>
<div class="paragraph">
<p>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 <a href="http://www.datanucleus.org:15080/products/accessplatform_5_1/jdo/mapping.html#schema_rdbms_views">support this</a>.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="mixins"><a class="anchor" href="#mixins"></a>Mixins</h3>
<div class="paragraph">
<p>The final type of domain object is the <strong>mixin</strong>.
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 <em>appears</em> to contribute the behaviour/state in the UI; the underlying domain class being "decorated" does not know this is happening.</p>
</div>
<div class="paragraph">
<p>This is therefore a key technique to allow the app to stay decoupled, so that it doesn&#8217;t degrade into the proverbial <a href="http://www.laputan.org/mud/mud.html#BigBallOfMud">"big ball of mud"</a>.
There&#8217;s a lot more discussion on this topic in <a href="#modules">modules</a>, below.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>In fact, we find mixins nicely balance inside-out vs outside-in ways of thinking about a system:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>inside-out tends to focus on the structure, the nouns that make up the domain.</p>
</li>
<li>
<p>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.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>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&#8217;s common for a user story to correspond to a new mixin.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>The Hotspot JVM has limited support for hot reloading; generally you can change method implementations but you cannot introduce new methods.
However, the <a href="https://dcevm.github.io/">DCEVM</a> open source project will patch the JVM to support much more complete hot reloading support.
There are also commercial products such as JRebel.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Details on how to actually write a mixin (the programming model for mixins) is
<a href="mixins.html" class="page">here</a>.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="sidebarblock">
<div class="content">
<div class="title">DCI Architecture</div>
<div class="paragraph">
<p>Mixins are an implementation of the <a href="http://www.artima.com/articles/dci_vision.html">DCI architecture</a> architecture, as formulated and described by <a href="https://en.wikipedia.org/wiki/Trygve_Reenskaug">Trygve Reenskaug</a> and <a href="https://en.wikipedia.org/wiki/Jim_Coplien">Jim Coplien</a>.
Reenskaug was the inventor of the MVC pattern (and also the external examiner for Richard Pawson&#8217;s <a href="../../../../../ug/fun/_attachments/core-concepts/Pawson-Naked-Objects-thesis.pdf">PhD thesis</a>), while Coplien has a long history in object-orientation, C++ and patterns.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="identifiers"><a class="anchor" href="#identifiers"></a>Identifiers</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The Apache Isis framework tracks the identity of each domain object.
This identity is represented to the end-user in human-readable form so that they know which object they are interacting with, and is also used and is available internally/for integrations.</p>
</div>
<div class="paragraph">
<p>This section explores these two related concepts.</p>
</div>
<div class="sect2">
<h3 id="title-and-icon-and-css-class"><a class="anchor" href="#title-and-icon-and-css-class"></a>Title, Icon etc.</h3>
<div class="paragraph">
<p>To allow the end-user to distinguish one domain object from another, it is rendered with a title and an icon.
The icon informally identifies the type of the domain object, while the title identifies the instance.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Title</p>
<div class="paragraph">
<p>The title of a domain object is shown in several places: as the main heading for an object; as a link text or tooltip for an object referencing another object, and also in tables representing collections of objects.</p>
</div>
<div class="paragraph">
<p>The title is not formally required to be a unique identify the object within its type, but it needs to be "unique enough" that a human user is able to distinguish one instance from another.</p>
</div>
<div class="paragraph">
<p>The title is usually just a simple string, but the framework also allows for the title to be translated into different locales.</p>
</div>
</li>
<li>
<p>Icon</p>
<div class="paragraph">
<p>Sometimes it&#8217;s helpful for the icon to represent more than just the object&#8217;s type; it might also indicate the state of an object.
For example, a shipped <code>Order</code> might have a slightly different icon to a yet-to-be-shipped <code>Order</code>; or a library book that is <code>loaned out</code> might be distinguished from one that is <code>available</code>.</p>
</div>
</li>
</ul>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Details on how to actually write titles and icons (the programming model) can be found <a href="ui.html#object-titles-and-icons" class="page">here</a>.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="oid"><a class="anchor" href="#oid"></a>OIDs</h3>
<div class="paragraph">
<p>As well as defining a <a href="concepts-patterns.html#metamodel" class="page">metamodel</a> of the structure (domain classes) of its domain objects, Apache Isis also manages the runtime instances of said domain objects.</p>
</div>
<div class="paragraph">
<p>When a domain entity is recreated from the database, the framework keeps track of its identity through an "OID": an object identifier.
Fundamentally this is a combination of its type (domain class), along with an identifier.
You can think of it as its "primary key", except across all domain entity types.</p>
</div>
<div class="paragraph">
<p>For portability and resilience, though, the object type is generally an alias for the actual domain class: thus "customers.CUS", say, rather than "com.mycompany.myapp.customers.Customer".
This is derived from an annotation.
The identifier meanwhile is always converted to a string.</p>
</div>
<div class="paragraph">
<p>Although simple, the OID is an enormously powerful concept: it represents a URI to any domain object managed by a given Apache Isis application.
With it, we have the ability to lookup any arbitrary domain objects.</p>
</div>
<div class="paragraph">
<p>Some examples:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>an OID allows sharing of information between users, eg as a deep link to be pasted into an email.</p>
</li>
<li>
<p>the information within an OID could be converted into a barcode, and stamped onto a PDF form.
When the PDF is scanned by the mail room, the barcode could be read to attach the correspondence to the relevant domain object.</p>
</li>
<li>
<p>as a handle to any object in an audit record, as used by <a href="../../../refguide/2.0.0-M5/applib/index/services/publishing/spi/EntityPropertyChangeSubscriber.html" class="page">EntityPropertyChangeSubscriber</a>;</p>
</li>
<li>
<p>similarly within implementations of <a href="../../../refguide/2.0.0-M5/applib/index/services/publishing/spi/CommandSubscriber.html" class="page">CommandSubscriber</a> to persist <code>Command</code> objects</p>
</li>
<li>
<p>similarly within implementations of <a href="../../../refguide/2.0.0-M5/applib/index/services/publishing/spi/ExecutionSubscriber.html" class="page">ExecutionSubscriber</a> to persist published action invocations</p>
</li>
<li>
<p>and of course both the <a href="../../../vro/2.0.0-M5/about.html" class="page">RestfulObjects viewer</a> and <a href="../../../vw/2.0.0-M5/about.html" class="page">Web UI (Wicket viewer)</a> use the oid tuple to look up, render and allow the user to interact with domain objects.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Although the exact content of an OID should be considered opaque by domain objects, it is possible for domain objects to obtain OIDs.
These are represented as <code>Bookmark</code>s, obtained from the <a href="../../../refguide/2.0.0-M5/applib/index/services/bookmark/BookmarkService.html" class="page">BookmarkService</a>.
Deep links meanwhile can be obtained from the <a href="../../../refguide/2.0.0-M5/applib/index/services/linking/DeepLinkService.html" class="page">DeepLinkService</a>.</p>
</div>
<div class="paragraph">
<p>OIDs can also be converted into XML format, useful for integration scenarios.
The <a href="../../../refguide/2.0.0-M5/schema/common.html" class="page">common schema</a> XSD defines the <code>oidDto</code> complex type for precisely this purpose.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="object-members"><a class="anchor" href="#object-members"></a>Object Members</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Every domain object in Apache Isis consists of (at most) three types of members:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>properties, such as a <code>Customer</code>'s <code>firstName</code></p>
</li>
<li>
<p>collections, such as a <code>Customer</code>'s <code>orders</code> collection of <code>Order</code>s</p>
</li>
<li>
<p>actions, such as a <code>Customer'</code>s <code>placeOrder(&#8230;&#8203;)</code> method.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>In addition, mixins act as contributors of behaviour to an underlying domain object.
Typically the behaviour being contributed is an action, but it could also be a derived property or a derived collection.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>What follows <em>is</em> a simplification; the Apache Isis programming model also recognizes a number of other supporting methods for domain object members, for associated business logic.
This is covered in more detail in <a href="business-rules.html" class="page">business rules</a>.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="sect2">
<h3 id="properties"><a class="anchor" href="#properties"></a>Properties</h3>
<div class="paragraph">
<p>Properties follow the standard getter/setter pattern, with the return type being a scalar (a value object or another entity or view model).</p>
</div>
<div class="paragraph">
<p>For example (using <a href="https://projectlombok.org/features/GetterSetter">Project Lombok</a> to avoid some boilerplate), with:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public class Customer
@Property <i class="conum" data-value="1"></i><b>(1)</b>
@PropertyLayout <i class="conum" data-value="2"></i><b>(2)</b>
@Getter @Setter
private String lastName;
...
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>The <a href="../../../refguide/2.0.0-M5/applib/index/annotation/Property.html" class="page">@Property</a> annotation defines additional domain-layer semantics</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>The <a href="../../../refguide/2.0.0-M5/applib/index/annotation/PropertyLayout.html" class="page">@PropertyLayout</a> annotation defines additional presentation-layer hints</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>From this the framework infers the <code>Customer</code> domain entity, which in turn has a <code>firstName</code> string <em>property</em>.</p>
</div>
<div class="paragraph">
<p><code>@Property</code> is not mandatory, though in many cases it will be present in order to specify additional semantics.</p>
</div>
<div class="paragraph">
<p><code>@PropertyLayout</code> is not mandatory either.
Whether it is present or not depends to some extent on your preferred style: the UI semantics can be specified either in code within this annotation, or can be specified through the companion <a href="ui.html#layout-file" class="page">layout file</a>.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Details on how to actually write properties in practice (the programming model) can be found <a href="object-members.html#properties" class="page">here</a>.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="collections"><a class="anchor" href="#collections"></a>Collections</h3>
<div class="paragraph">
<p>Like properties, collections are also represented by a getter and setter, however the return type is a <code>Collection</code> or subtype.</p>
</div>
<div class="paragraph">
<p>For example (again, using <a href="https://projectlombok.org/features/GetterSetter">Project Lombok</a>), with:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public class Customer
@Collection <i class="conum" data-value="1"></i><b>(1)</b>
@CollectionLayout <i class="conum" data-value="2"></i><b>(2)</b>
@Getter @Setter
private SortedSet&lt;Order&gt; orders = new TreeSet&lt;Order&gt;(); <i class="conum" data-value="3"></i><b>(3)</b>
...
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>The <a href="../../../refguide/2.0.0-M5/applib/index/annotation/Collection.html" class="page">@Collection</a> annotation defines additional domain-layer semantics</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>The <a href="../../../refguide/2.0.0-M5/applib/index/annotation/CollectionLayout.html" class="page">@CollectionLayout</a> annotation defines additional presentation-layer hints</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>The most commonly a <code>java.util.SortedSet</code> for entities obtained from an RDBMS (with set semantics).
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
all entities should define a natural ordering so that when rendered in the UI they will be ordered "meaningfully" to the end-user.
</td>
</tr>
</table>
</div></td>
</tr>
</table>
</div>
<div class="paragraph">
<p>From this the framework infers the <code>orders</code> <em>collection</em>.</p>
</div>
<div class="paragraph">
<p>As with properties, the <code>@Collection</code> annotation is not mandatory, though in many cases it will be present in order to specify additional semantics.</p>
</div>
<div class="paragraph">
<p>Similarly, <code>@CollectionLayout</code> is not mandatory either.
Whether it is present or not depends to some extent on your preferred style: the UI semantics can be specified either in code within this annotation, or can be specified through the companion <a href="ui.html#layout-file" class="page">layout file</a>.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Details on how to actually write collections in practice (the programming model) can be found <a href="object-members.html#collections" class="page">here</a>.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="actions"><a class="anchor" href="#actions"></a>Actions</h3>
<div class="paragraph">
<p>While <a href="object-members.html#properties" class="page">properties</a> and <a href="object-members.html#collections" class="page">collections</a> define the state held by a domain object (its "know what" responsibilities), actions define the object&#8217;s behaviour (its "know how-to" responsibilities).</p>
</div>
<div class="paragraph">
<p>An application that consists only of domain entities with just "know-what" responsibilities is pretty dumb: it requires that the end-user know the business rules and doesn&#8217;t modify the state of the domain objects such that they are invalid (for example, an "end date" being before a "start date").
Such applications are often called CRUD applications (create/read/update/delete).</p>
</div>
<div class="paragraph">
<p>In more complex domains, it&#8217;s not realistic/feasible to expect the end-user to have to remember all the different business rules that govern the valid states for each domain object.
Actions allow those business rules to be encoded programmatically.
Those actions can either be defined in the domain class itself, or can be contributed by way of a <a href="#mixins">mixin</a>.</p>
</div>
<div class="paragraph">
<p>The general philosophy for an Apache Isis (naked objects) application is <em>not</em> to constrain the end-user in how they interact with the UI: it doesn&#8217;t attempt to define a rigid business process.
However, it <em>does</em> aim to ensure that business rule invariants are maintained, that is that domain objects aren&#8217;t allowed to enter into an invalid state.</p>
</div>
<div class="paragraph">
<p>For simple domain applications, you may want to start prototyping only with properties, and only later introduce actions (representing the most common business operations).
But an alternative approach, recommended for more complex applications, is actually to start the application with all properties non-editable.
Then, as the end-user requires the ability to modify some state, there is a context in which to ask the question "why does this state need to change?" and "are their any side-effects?" (ie, other state that changes at the same time, or other behaviour that should occur).
If the state change is simple, for example just being able to correct an invalid address, or adding a note or comment, then that can probably be modelled as a simple editable property.
But if the state change is more complex, then most likely an action should be used instead.</p>
</div>
<div class="paragraph">
<p>Broadly speaking, actions are those <code>public</code> methods that do not represent properties or collections.</p>
</div>
<div class="paragraph">
<p>For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public class Customer {
@Action <i class="conum" data-value="1"></i><b>(1)</b>
@ActionLayout <i class="conum" data-value="2"></i><b>(2)</b>
public Customer placeOrder(
@Parameter <i class="conum" data-value="3"></i><b>(3)</b>
@ParameterLayout <i class="conum" data-value="4"></i><b>(4)</b>
Product p,
@Parameter
@ParameterLayout
int quantity) {
/* ... */
}
...
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>The <a href="../../../refguide/2.0.0-M5/applib/index/annotation/Action.html" class="page">@Action</a> annotation defines additional domain-layer semantics</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>The <a href="../../../refguide/2.0.0-M5/applib/index/annotation/ActionLayout.html" class="page">@ActionLayout</a> annotation defines additional presentation-layer hints</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>The <a href="../../../refguide/2.0.0-M5/applib/index/annotation/Parameter.html" class="page">@Parameter</a> annotation defines additional domain-layer semantics</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b>4</b></td>
<td>The <a href="../../../refguide/2.0.0-M5/applib/index/annotation/ParameterLayout.html" class="page">@ParameterLayout</a> annotation defines additional presentation-layer hints</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>From this the framework infers a the <code>placeOrder</code> <em>action</em>.</p>
</div>
<div class="paragraph">
<p>Whether the <code>@Action</code> annotation is required to identify an action method is configurable; some teams prefer actions to be explicitly called out, others prefer that any "left over" public methods are identified as actions.</p>
</div>
<div class="paragraph">
<p>The use of <code>@ActionLayout</code> is optional, the UI semantics can be specified either in code within this annotation, or can be specified through the companion <a href="ui.html#layout-file" class="page">layout file</a>.</p>
</div>
<div class="paragraph">
<p>As with properties, both <code>@Parameter</code> and <code>@ParameterLayout</code> are also optional.
Note though that UI hints for parameters <em>cannot</em> be specified in the layout file.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Details on how to actually write actions in practice (the programming model) can be found <a href="object-members.html#actions" class="page">here</a>.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="business-rules"><a class="anchor" href="#business-rules"></a>Business Rules</h2>
<div class="sectionbody">
<div class="paragraph">
<p>When a domain object is rendered in the UI or the end-user interacts with the domain object through the UI, the framework applies a series of precondition business rules to each object member (property, collection or action).</p>
</div>
<div class="paragraph">
<p>When the object is being rendered, the framework checks:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>is the object member visible?</p>
<div class="paragraph">
<p>Members that are not visible are simply omitted from the page.
If all the members in a fieldset (property group) are hidden, then the fieldset is not shown.
If all the members in a tab are hidden, then the tab is not shown.
If all the members of the object are hidden, then a "404" style message ("no such object") is returned to the user.</p>
</div>
</li>
<li>
<p>if the object member is visible, is the object member enabled?</p>
<div class="paragraph">
<p>An enabled property can be edited (otherwise it is read-only), and an enabled action can be invoked (otherwise it&#8217;s button is "greyed-out").
Note that collections are always read-only.</p>
</div>
</li>
<li>
<p>for enabled object members, if the user then interacts with that member, are the supplied values valid (can the user "do it").</p>
<div class="paragraph">
<p>For an editable property this means validating the proposed new value of the property.
For an invokable action this means validating that arguments being used to invoke the action.</p>
</div>
</li>
</ul>
</div>
<div class="paragraph">
<p>One way to remember this is: <strong>"see it, use it, do it"</strong></p>
</div>
<div class="sidebarblock">
<div class="content">
<div class="title">See it, use it, do it</div>
<div class="ulist">
<ul>
<li>
<p>is the object member visible?</p>
</li>
<li>
<p>if so, is the object member enabled?</p>
</li>
<li>
<p>if so, are the supplied values valid? (can the user "do" it)?</p>
</li>
</ul>
</div>
</div>
</div>
<div class="paragraph">
<p>The framework provides a multitude of ways to implement these business rules.
The simplest approach is to just implement the business rules imperatively in the domain object, using a supporting method.
For example,</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public Customer placeOrder(Product p, int quantity) {
// ...
}
public boolean hidePlaceOrder() { <i class="conum" data-value="1"></i><b>(1)</b>
return isBlacklisted();
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>supporting method, invoked before rendering the customer.</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>In this example the "place order" action would not be visible for any customer that had been blacklisted.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Details on how to actually write business rules (the programming model) can be found <a href="business-rules.html" class="page">here</a>.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="events"><a class="anchor" href="#events"></a>Events</h2>
<div class="sectionbody">
<div class="paragraph">
<p>When the framework renders a domain object, and as the end-user interacts with the domain object, the framework it emits multiple events using the intra-process <a href="../../../refguide/2.0.0-M5/applib/index/services/eventbus/EventBusService.html" class="page">event bus</a>.
These events enable other domain services (possibly in other modules) to influence how the domain object is rendered, or to perform side-effects or even veto an action invocation.</p>
</div>
<div class="paragraph">
<p>To receive the events, the domain service should subscribe to the <a href="../../../refguide/2.0.0-M5/applib/index/services/eventbus/EventBusService.html" class="page">EventBusService</a>, and implement an appropriately annotated method to receive the events.</p>
</div>
<div class="paragraph">
<p>The framework has several categories of events: domain events, UI events and lifecycle events.
These are explored in the sections below.</p>
</div>
<div class="sect2">
<h3 id="domain-events"><a class="anchor" href="#domain-events"></a>Domain Events</h3>
<div class="paragraph">
<p>Domain events are fired&#8201;&#8212;&#8201;through the internal <a href="../../../refguide/2.0.0-M5/applib/index/services/eventbus/EventBusService.html" class="page">event bus</a>&#8201;&#8212;&#8201;for every user interaction with each object member (property, collection or action).</p>
</div>
<div class="paragraph">
<p>By default, rendering a property causes a <code>PropertyDomainEvent</code> to be fired, though the <a href="../../../refguide/2.0.0-M5/applib/index/annotation/Property.html#domainEvent" class="page">@Property#domainEvent()</a> attribute allows a custom subclass to be specified if necessary.
Similarly, rendering a collection causes a <code>CollectionDomainEvent</code> to be fired, and rendering an action causes an <code>ActionDomainEvent</code> to be fired.</p>
</div>
<div class="paragraph">
<p>In fact, each event can be fired up to five times, with the event&#8217;s <code>getEventPhase()</code> method indicating to the subscriber the phase:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>hide</strong> phase allows the subscriber to hide the member</p>
</li>
<li>
<p><strong>disable</strong> phase allows the subscriber to disable the member.</p>
<div class="paragraph">
<p>For a property this makes it read-only; for an action this makes it "greyed out".
(Collections are implicitly read-only).</p>
</div>
</li>
<li>
<p><strong>validate</strong> phase allows the subscriber to validate the proposed change.</p>
<div class="paragraph">
<p>For a property this means validating the proposed new value of the property; for an action this means validating the action parameter arguments.
For example, a referential integrity restrict could be implemented here.</p>
</div>
</li>
<li>
<p><strong>executing</strong> phase is prior to the actual property edit/action invocation, allowing the subscriber to perform side-effects.</p>
<div class="paragraph">
<p>For example, a cascade delete could be implemented here.</p>
</div>
</li>
<li>
<p><strong>executed</strong> phase is after the actual property edit/action invocation.</p>
<div class="paragraph">
<p>For example, a business audit event could be implemented here.</p>
</div>
</li>
</ul>
</div>
<div class="paragraph">
<p>For more details on the actual domain event classes, see the <a href="../../../refguide/2.0.0-M5/applib-classes/events.html#domain-event-classes" class="page">domain event</a> section of the relevant reference guide.</p>
</div>
</div>
<div class="sect2">
<h3 id="ui-events"><a class="anchor" href="#ui-events"></a>UI Events</h3>
<div class="paragraph">
<p>As explained <a href="#title-and-icon-and-css-class">earlier</a>, to allow the end-user to distinguish one domain object from another, it is rendered with a title and an icon.</p>
</div>
<div class="paragraph">
<p><a href="ui.html#object-titles-and-icons" class="page">Normally</a> the code to return title and icon of an object is part of the domain object&#8217;s implementation.
However, UI events allow this title and icon to be provided instead by a subscriber.
UI events have higher precedence than the other mechanisms of supplying a title.</p>
</div>
<div class="paragraph">
<p>If annotated with <a href="../../../refguide/2.0.0-M5/applib/index/annotation/DomainObjectLayout.html#titleUiEvent" class="page">@DomainObjectLayout#titleUiEvent()</a>, the appropriate (subclass of) <code>TitleUiEvent</code> will be emitted.
Similarly for <a href="../../../refguide/2.0.0-M5/applib/index/annotation/DomainObjectLayout.html#iconUiEvent" class="page">#iconUiEvent()</a>.
In addition, it is possible to use events to obtain a CSS class to render with the domain object, using <a href="../../../refguide/2.0.0-M5/applib/index/annotation/DomainObjectLayout.html#cssClassUiEvent" class="page">#cssClassUiEvent()</a>, and to select an alternate <a href="ui.html#layout-file" class="page">layout file</a> using <a href="../../../refguide/2.0.0-M5/applib/index/annotation/DomainObjectLayout.html#layoutUiEvent" class="page">#layoutUiEvent()</a>.</p>
</div>
<div class="paragraph">
<p>There are two use cases where this feature is useful:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>the first is to override the title/icon/CSS class/layout of 3rd party library code, for example as provided by the <a href="../../../security/2.0.0-M5/secman/about.html" class="page">SecMan</a> extension.</p>
</li>
<li>
<p>the second is for <a href="view-models.html#jaxb" class="page">JAXB-style view models</a> which are code generated from XSDs and so cannot have any dependencies on the rest of the Apache Isis framework.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>In this second case a subscriber on the default events can provide a title and icon for such an object, with the behaviour provided using <a href="#mixins">mixins</a>.</p>
</div>
</div>
<div class="sect2">
<h3 id="lifecycle-events"><a class="anchor" href="#lifecycle-events"></a>Lifecycle Events</h3>
<div class="paragraph">
<p>Lifecycle events allow domain object subscribers to listen for changes to the persistence state of domain entities, and act accordingly.</p>
</div>
<div class="admonitionblock warning">
<table>
<tr>
<td class="icon">
<i class="fa icon-warning" title="Warning"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Lifecycle events are <em>not</em> fired for view models.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>The lifecycle events supported are:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>created</strong></p>
<div class="paragraph">
<p>Entity has just been instantiated.
Note that this requires that the object is instantiated using the framework, see <a href="domain-entities-and-services.html#instantiating" class="page">here</a> for further discussion.</p>
</div>
</li>
<li>
<p><strong>loaded</strong></p>
<div class="paragraph">
<p>Entity has just retrieved/rehydrated from the database</p>
</div>
</li>
<li>
<p><strong>persisting</strong></p>
<div class="paragraph">
<p>Entity is about to be inserted/saved (ie for the first time) into the database</p>
</div>
</li>
<li>
<p><strong>persisted</strong></p>
<div class="paragraph">
<p>Entity has just been inserted/saved (ie for the first time) into the database</p>
</div>
</li>
<li>
<p><strong>updating</strong></p>
<div class="paragraph">
<p>The (already persistent) entity about to be flushed in the database</p>
</div>
</li>
<li>
<p><strong>updated</strong></p>
<div class="paragraph">
<p>The (already persistent) entity has just been flushed to the database</p>
</div>
</li>
<li>
<p><strong>removing</strong></p>
<div class="paragraph">
<p>The (already persistent) entity is about to be deleted from the database</p>
</div>
</li>
</ul>
</div>
<div class="paragraph">
<p>For example, if annotated with <a href="../../../refguide/2.0.0-M5/applib/index/annotation/DomainObject.html#updatingLifecycleEvent" class="page">@DomainObjectLayout#updatingLifecycleEvent</a>, the appropriate (subclass of) <code>ObjectUpdatingEvent</code> will be emitted.</p>
</div>
<div class="paragraph">
<p>There is no lifecycle event for "entity creating" because (obviously) the framework doesn&#8217;t know about newly created objects until they have been created.
Similarly, there is no lifecycle event for entities that have been removed because it is not valid to "touch" a domain entity once deleted.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="modules"><a class="anchor" href="#modules"></a>Modules</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Enabling and ensuring modularity is a <a href="concepts-patterns.html#modular" class="page">key principle</a> for the Apache Isis framework.
Modularity is the only way to ensure that a complex application domain does not over time degenerate into the infamous "big ball of mud", software that is difficult, dangerous and expensive to change.</p>
</div>
<div class="paragraph">
<p>Modules chunk up the overall application into smaller pieces, usually a pacakge and subpackages.
The smaller pieces can be either tiers (presentation / domain / persistence) or functional architectural layers (eg customer vs orders vs products vs invoice etc).
Because Apache Isis takes care of the presentation and persistence tiers, modules for us focuses just on the important bit: considering how the functionality within the domain model should be broken up into modules, and determining the dependencies between those modules.</p>
</div>
<div class="sect2">
<h3 id="rules-of-thumb"><a class="anchor" href="#rules-of-thumb"></a>Rules of Thumb</h3>
<div class="paragraph">
<p>The two main rule of thumbs for dependencies are:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>there should be no cyclic dependencies (the module dependencies should form an acyclic graph), and</p>
</li>
<li>
<p>unstable modules should depend upon stable modules, rather than the other way around.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>By "unstable" we don&#8217;t mean buggy, rather this relates to its likelihood to change its structure or behaviour over time: in other words its stability as a core set of concepts upon which other stuff can depend.
Reference data (calendars, tax rates, lookups etc) are generally stable, as are "golden" concept such as counterparties / legal entities or financial accounts.
Transactional concepts such as invoices or agreements is perhaps more likely to change.
But this stuff is domain specific.</p>
</div>
</div>
<div class="sect2">
<h3 id="decoupling"><a class="anchor" href="#decoupling"></a>Decoupling</h3>
<div class="paragraph">
<p>Having broken up a domain into multiple modules, there is still a need for higher level modules to use lower level modules, and the application must still appear as a coherent whole to the end-user.</p>
</div>
<div class="paragraph">
<p>The key features that Apache Isis provides to support this are:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>dependency injection of services</p>
<div class="paragraph">
<p>Both <a href="../../../refguide/2.0.0-M5/applib-svc/about.html" class="page">framework-defined</a> domain services and application-defined services (eg repositories and factories) are injected everywhere, using the <code>@javax.inject.Inject</code> annotation (Spring&#8217;s <code>@Autowired</code> can also be used).</p>
</div>
<div class="paragraph">
<p>By "everywhere", we mean not just into domain services, but <em>also</em> injected into domain entities and view models.
This enables us to implement behaviourally complete domain objects (if we so wish).</p>
</div>
</li>
<li>
<p><a href="#mixins">mixins</a> that allow functionality defined in one module to appear (in the UI) to be provided by some other module.</p>
<div class="paragraph">
<p>For example, a <em>Document</em> module might allow <code>Document</code> objects to be attached to any arbitrary domain object (such as <code>Order</code> or <code>Customer</code>) in other modules.
A mixin would allow the UI for a <code>Customer</code> to also display these attached <code>Document</code>s, even though the <em>Customer</em> module would have no knowledge of/dependency on the <em>Workflow</em> module.
(More on this example <a href="#inverting-dependencies">below</a>).</p>
</div>
<div class="paragraph">
<p>Dependencies are also injected into mixins.
A common technique is to factor out from domain objects into mixins and then generalise.</p>
</div>
</li>
<li>
<p>the internal <a href="../../../refguide/2.0.0-M5/applib/index/services/eventbus/EventBusService.html" class="page">event bus</a> allows modules to influence other modules.</p>
<div class="paragraph">
<p>A subscriber in one module can subscribe to events emitted by domain objects in another module.
These events can affect both the UI (eg hiding or disabling <a href="#object-members">object members</a>, or allowing or vetoing interactions).</p>
</div>
</li>
</ul>
</div>
<div class="paragraph">
<p>A good example of this last is supporting (what in an RDBMS we would call) referential integrity.
Suppose the <code>customers</code> module has a <code>Customer</code> object and a <code>EmailAddress</code> object, with a customer having a collection of email addresses.
A <code>communications</code> module might then use those email addresses to create <code>EmailCommunication</code>s.</p>
</div>
<div class="paragraph">
<p>If the <code>customers</code> module wants to delete an <code>EmailAddress</code> then the <code>communications</code> module will probably want to veto this because they are "in use" by those <code>EmailCommunication</code>s.
Or, it might conceivably perform a cascade delete of all associated communications.
Either way, the <code>communications</code> module receives an internal event representing the intention to delete the <code>EmailAddress</code>.
It can then act accordingly, either vetoing the interaction or performing the cascade delete.
The <code>customers</code> module for its part does not know anything about this other module.</p>
</div>
</div>
<div class="sect2">
<h3 id="inverting-dependencies"><a class="anchor" href="#inverting-dependencies"></a>Inverting Dependencies</h3>
<div class="paragraph">
<p>If we get the dependencies wrong (that is, our initial guess on stability is proven incorrect over time) then there are a couple of techniques we can use:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>use the <a href="https://en.wikipedia.org/wiki/Dependency_inversion_principle">dependency inversion principle</a> to introduce an abstraction representing the dependency.</p>
</li>
<li>
<p>move functionality, eg by factoring it out into <a href="#mixins">mixins</a> into the other module or into a third module which depends on the other modules that had a bidirectional relationship</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Mixins in particular allow dependencies to be inverted, so that the dependencies between modules can be kept acyclic and under control.</p>
</div>
<div class="paragraph">
<p>For example, suppose that we send out <code>Invoice</code>s to <code>Customer</code>s.
We want the invoices to know about customers, but not vice versa.
We could surface the set of invoices for a customer using a <code>Customer_invoices</code> mixin:</p>
</div>
<div class="imageblock kroki">
<div class="content">
<img src="_images/diag-1e6be3ab94573991b764958ec88db5a8beb17408.svg" alt="`invoices` module contributes to `customers`">
</div>
<div class="title">Figure 2. <code>invoices</code> module contributes to <code>customers</code></div>
</div>
<div class="paragraph">
<p>In the UI, when rendering a <code>Customer</code>, we would also be presented with the associated set of <code>Invoice</code>s.</p>
</div>
<div class="paragraph">
<p>We can also use mixins for dependencies that are in the other direction.
For example, suppose we have a mechanism to attach <code>Document</code>s to arbitrary domain objects.
The documents module does not depend on any other modules, but provides a <code>DocumentHolder</code> marker interface.
We can therefore attach documents to a <code>Customer</code> by having <code>Customer</code> implement this marker interface:</p>
</div>
<div class="imageblock kroki">
<div class="content">
<img src="_images/diag-3c9c462c5d1913ae10a71f94738a70175be7f380.svg" alt="`customers` depends upon contributions of `documents`">
</div>
<div class="title">Figure 3. <code>customers</code> depends upon contributions of <code>documents</code></div>
</div>
</div>
<div class="sect2">
<h3 id="defining-modules"><a class="anchor" href="#defining-modules"></a>Defining Modules</h3>
<div class="paragraph">
<p>In the context of Java applications, modularity is a rather overloaded term.
We have Maven modules, Java 9 modules and we also have Spring <a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Configuration.html">@Configuration</a>s, which define a set of domain services.</p>
</div>
<div class="paragraph">
<p>In the context of Apache Isis, a module is actually the last of these, a Spring module.</p>
</div>
<div class="paragraph">
<p>The <a href="../../../docs/2.0.0-M5/starters/simpleapp.html" class="page">simpleapp starter app</a> provide some structure and illustrates the idioms.
To summarise:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>by convention, we have one <code>@Configuration</code> module per Maven module.</p>
<div class="paragraph">
<p>This is at the root package of the maven module.</p>
</div>
</li>
<li>
<p>all of the domain classes (domain objects and services) are part of that Maven module.</p>
<div class="paragraph">
<p>All are annotated or meta-annotated with Spring&#8217;s <a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/stereotype/Component.html">@Component</a> annotation, and Spring&#8217;s <a href="https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/annotation/ComponentScan.html">@ComponentScan</a> is used to discover these from the classpath.</p>
</div>
</li>
<li>
<p>Spring&#8217;s <a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Import.html">@Import</a> is used to express a dependency between each "configuration" module.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>By convention, we have just one Spring module to each Maven module.
This means that the dependencies between Maven modules (using <code>&lt;dependency&gt;</code> are mirrored in the Spring module&#8217;s <code>@Import</code> statements).
We can therefore rely on Maven to ensure there are no cyclic dependencies: the application simply won&#8217;t compile if we introduce a cycle.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Details on how to actually define modules can be found <a href="modules.html" class="page">here</a>.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>If the above convention is too officious,then you could choose to have multiple Spring modules per Maven module, but you will need to watch out for cycles.</p>
</div>
<div class="paragraph">
<p>In such cases (proprietary) tools such as <a href="https://structure101.com/">Structure 101</a> can be used to help detect and visualize such cycles.
Or, (open source) libraries such as <a href="https://www.archunit.org/">ArchUnit</a> or <a href="https://jqassistant.org/">jQAssistant</a> can help enforce architectural layering to prevent the issue arising in the first place.
(These tools can enforce other conventions, too, so are well worth exploring).</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="programming-model"><a class="anchor" href="#programming-model"></a>Programming Model</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Apache Isis works by building a <a href="concepts-patterns.html#metamodel" class="page">metamodel</a> of the domain objects: entities, domain services, view models and mixins.
Dependent on the <a href="#type-of-domain-objects">sort of domain object</a>, the class methods represent both state&#8201;&#8212;&#8201;(single-valued) <a href="#properties">properties</a> and (multi-valued) <a href="#collections">collections</a>&#8201;&#8212;&#8201;and behaviour&#8201;&#8212;&#8201;<a href="#actions">actions</a>.</p>
</div>
<div class="paragraph">
<p>More specifically, both <a href="#domain-entities">entities</a> and <a href="#view-models">view models</a> can have properties, collections and actions, while <a href="#domain-services">domain services</a> have just actions.
<a href="#mixins">Mixins</a> also define only actions, though depending on their semantics they may be rendered as derived properties or collections on the domain object to which they contribute.</p>
</div>
<div class="paragraph">
<p>In the automatically generated UI a property is rendered as a field.
This can be either of a value type (a string, number, date, boolean etc) or can be a reference to another entity.
A collection is generally rendered as a table.</p>
</div>
<div class="paragraph">
<p>Additional <a href="business-rules.html" class="page">business rules</a> semantics are inferred both imperatively from <em>supporting methods</em> (such as <code>disableXxx()</code>) and declaratively from <a href="../../../refguide/2.0.0-M5/applib-ant/about.html" class="page">annotations</a>.</p>
</div>
<div class="paragraph">
<p>Taken together this set of conventions are what we call the <em><strong>Apache Isis Programming Model</strong></em>.
In essence, these conventions are just an extension of the pojo / JavaBean standard of yesteryear: properties and collections are getters/setters, while actions are simply any remaining <code>public</code> methods.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
<div class="paragraph">
<p>In fact, the Apache Isis programming model is extensible; you can teach Apache Isis new programming conventions and you can remove existing ones; ultimately they amount to syntax.
The only real fundamental that can&#8217;t be changed is the notion that objects consist of properties, collections and actions.</p>
</div>
<div class="paragraph">
<p>You can learn more about extending Apache Isis programming model <a href="../btb/programming-model.html" class="page">here</a>.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
</article>
<aside class="article-aside toc hide-for-print" role="navigation">
<p class="toc-title">On this page</p>
<div id="article-toc"></div>
</aside>
</main>
</div>
<footer class="footer">
<div class="content">
<div class="copyright">
<p>
Copyright © 2010~2021 The Apache Software Foundation, licensed under the Apache License, v2.0.
<br/>
Apache, the Apache feather logo, Apache Isis, and the Apache Isis project logo are all trademarks of The Apache Software Foundation.
</p>
</div>
<div class="revision">
<p>Revision: 2.0.0-M5.20210409-1206</p>
</div>
</div>
</footer>
<script src="../../../_/js/site.js"></script>
<script async src="../../../_/js/vendor/highlight.js"></script>
<script src="../../../_/js/vendor/jquery-3.4.1.min.js"></script>
<script src="../../../_/js/vendor/jquery-ui-1.12.1.custom.widget-only.min.js"></script>
<script src="../../../_/js/vendor/jquery.tocify.min.js"></script>
<script>
$(function() {
$("#article-toc").tocify( {
showEffect: "slideDown",
hashGenerator: "pretty",
hideEffect: "slideUp",
selectors: "h2, h3",
scrollTo: 120,
smoothScroll: true,
theme: "jqueryui",
highlightOnScroll: true
} );
});
</script>
<script src="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.js"></script>
<script>
function focusSearchInput () { document.querySelector('#algolia-search-input').focus() }
var search = docsearch({
appId: '5ISP5TFAEN',
apiKey: '0fc51c28b4ad46e7318e96d4e97fab7c',
indexName: 'isis-apache-org',
inputSelector: '#algolia-search-input',
autocompleteOptions: { hint: false, keyboardShortcuts: ['s'] },
debug: false,
}).autocomplete
search.on('autocomplete:closed', function () { search.autocomplete.setVal() })
focusSearchInput()
window.addEventListener('load', focusSearchInput);
</script>
<!--
docsearch options:
https://docsearch.algolia.com/docs/behavior/
-->
<!--
https://www.algolia.com/doc/api-reference/api-parameters/
algoliaOptions: { hitsPerPage: 6 },
-->
</body>
</html>