[#object-members]
= Object Members

: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:


Every domain object in Apache Isis consists of (at most) three types of members:

* properties, such as a ``Customer``'s `firstName`

* collections, such as a ``Customer``'s `orders` collection of ``Order``s

* actions, such as a ``Customer'``s `placeOrder(...)` method.

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.


[NOTE]
====
What follows _is_ 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 xref:userguide:fun:business-rules.adoc[business rules].
====



[#properties]
== Properties

Properties follow the standard getter/setter pattern, with the return type being a scalar (a value object or another entity or view model).


For example (using link:https://projectlombok.org/features/GetterSetter[Project Lombok] to avoid some boilerplate), with:

[source,java]
----
public class Customer
    @Property                       <.>
    @PropertyLayout                 <.>
    @Getter @Setter
    private String lastName;
    ...
}
----
<.> The xref:refguide:applib:index/annotation/Property.adoc[@Property] annotation defines additional domain-layer semantics
<.> The xref:refguide:applib:index/annotation/PropertyLayout.adoc[@PropertyLayout] annotation defines additional presentation-layer hints

From this the framework infers the `Customer` domain entity, which in turn has a `firstName` string _property_.

`@Property` is not mandatory, though in many cases it will be present in order to specify additional semantics.

`@PropertyLayout` 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 xref:userguide:fun:ui.adoc#layout-file-styles[layout file].

[TIP]
====
Details on how to actually write properties in practice (the programming model) can be found xref:userguide:fun:object-members.adoc#properties[here].
====


[#collections]
== Collections

Like properties, collections are also represented by a getter and setter, however the return type is a `Collection` or subtype.

For example (again, using link:https://projectlombok.org/features/GetterSetter[Project Lombok]), with:

[source,java]
----
public class Customer
    @Collection                                             <.>
    @CollectionLayout                                       <.>
    @Getter @Setter
    private SortedSet<Order> orders = new TreeSet<Order>(); <.>
    ...
}
----
<.> The xref:refguide:applib:index/annotation/Collection.adoc[@Collection] annotation defines additional domain-layer semantics
<.> The xref:refguide:applib:index/annotation/CollectionLayout.adoc[@CollectionLayout] annotation defines additional presentation-layer hints
<.> The most commonly a `java.util.SortedSet` for entities obtained from an RDBMS (with set semantics).
+
TIP: all entities should define a natural ordering so that when rendered in the UI they will be ordered "meaningfully" to the end-user.

From this the framework infers the `orders` _collection_.

As with properties, the `@Collection` annotation is not mandatory, though in many cases it will be present in order to specify additional semantics.

Similarly, `@CollectionLayout` 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 xref:userguide:fun:ui.adoc#layout-file-styles[layout file].

[TIP]
====
Details on how to actually write collections in practice (the programming model) can be found xref:userguide:fun:object-members.adoc#collections[here].
====


[#actions]
== Actions

While xref:userguide:fun:object-members.adoc#properties[properties] and xref:userguide:fun:object-members.adoc#collections[collections] define the state held by a domain object (its "know what" responsibilities), actions define the object's behaviour (its "know how-to" responsibilities).

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'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).

In more complex domains, it'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 xref:overview.adoc#mixins[mixin].

The general philosophy for an Apache Isis (naked objects) application is _not_ to constrain the end-user in how they interact with the UI: it doesn't attempt to define a rigid business process.
However, it _does_ aim to ensure that business rule invariants are maintained, that is that domain objects aren't allowed to enter into an invalid state.

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.

Broadly speaking, actions are those `public` methods that do not represent properties or collections.

For example:

[source,java]
----
public class Customer {
    @Action                       // <.>
    @ActionLayout                 // <.>
    public Customer placeOrder(
        @Parameter                // <.>
        @ParameterLayout          // <.>
        Product p,
        @Parameter
        @ParameterLayout
        int quantity) {
        /* ... */
    }
    ...
}
----
<.> The xref:refguide:applib:index/annotation/Action.adoc[@Action] annotation defines additional domain-layer semantics
<.> The xref:refguide:applib:index/annotation/ActionLayout.adoc[@ActionLayout] annotation defines additional presentation-layer hints
<.> The xref:refguide:applib:index/annotation/Parameter.adoc[@Parameter] annotation defines additional domain-layer semantics
<.> The xref:refguide:applib:index/annotation/ParameterLayout.adoc[@ParameterLayout] annotation defines additional presentation-layer hints

From this the framework infers a the `placeOrder` _action_.

Whether the `@Action` 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.

The use of `@ActionLayout` is optional, the UI semantics can be specified either in code within this annotation, or can be specified through the companion xref:userguide:fun:ui.adoc#layout-file-styles[layout file].

As with properties, both `@Parameter` and `@ParameterLayout` are also optional.
Note though that UI hints for parameters _cannot_ be specified in the layout file.

[TIP]
====
Details on how to actually write actions in practice (the programming model) can be found xref:userguide:fun:object-members.adoc#actions[here].
====
