| ////////////////////// |
| * Copyright (c) 2007-2012, Niclas Hedhman. All Rights Reserved. |
| * |
| * Licensed 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. |
| ////////////////////// |
| |
| [[howto-assemble-application,Assemble an Application]] |
| = Assemble an Application = |
| We receive a lot of questions about how applications should be assembled, and since we don't have any XML to "fill in" |
| and everything is to be done programmatically, it escalates the need to provide more hands-on explanation of how this is |
| done. |
| |
| If you want to reproduce what's explained in this tutorial, remember to depend on the Core Bootstrap artifact: |
| |
| include::../../../../core/bootstrap/build/docs/buildinfo/artifact.txt[] |
| |
| At runtime you will need the Core Runtime artifact too. See the <<howto-depend-on-zest>> tutorial for details. |
| |
| == Basics == |
| |
| First let's recap the structural requirements of Zest; |
| |
| * There is one and only one Application instance per Zest™ Runtime. |
| * Every Application must contain one or more Layers. |
| * All Composites must be declared in one or more Modules. |
| * Each Module belong to a Layer. |
| * Layers are ordered in hierarchies, from simple to complex. |
| * Access to Composites are limited by visibility rules. |
| |
| Ok, that was quite a handful. Let's look at them one by one. |
| |
| == Application == |
| |
| The first one means that for each Zest™ Runtime you start, there will be exactly one application. As far as we know, Zest |
| is fully isolated, meaning there are no static members being populated and such. |
| |
| == Layers == |
| |
| Layers are the super-structures of an application. We have been talking about them for decades, drawn them on paper and |
| whiteboards (or even black boards for those old enough), and sometimes organized the codebases along such boundaries. |
| But, there has been little effort to enforce the Layer mechanism in code, although it is an extremely powerful |
| construct. First of all it implies directional dependency and a high degree of order, spagetti code is reduced if |
| successfully implemented. For Zest, it means that we can restrict access to Composite and Object declarations, so that |
| higher layers can not reach them incidentally. You can enforce architecture to a high degree. You can require all |
| creation of composites to go through an exposed Factory, which doesn't require the Composite to be public. And so on. |
| Layers have hierarchy, i.e. one layer is top of one or more layers, and is below one or more layers, except for the |
| layers at the top and bottom. You could have disjoint layers, which can't access each other, meaning a couple of layers |
| that are both the top and bottom. |
| |
| == Modules == |
| |
| The Module concept has also been around forever. And in Zest™ we also makes the Modules explicit. Each Module belong to a |
| Layer, and for each Module you declare the Composite and Object types for that Module, together with a Visibility rule, |
| one of; application, layer, module. |
| |
| == Visibility == |
| |
| The Visibility rules are perhaps the most powerful aspect of the above. Visibility is a mechanism that kicks in whenever |
| a Composite type need to be looked up. It defines both the scoping rules of the client as well as the provider. A lookup |
| is either a direct reference, such as |
| |
| [snippet,java] |
| ----------- |
| source=manual/src/main/java/org/qi4j/manual/recipes/assemble/Docs.java |
| tag=direct |
| ----------- |
| |
| or an indirect lookup, such as |
| |
| [snippet,java] |
| ----------- |
| source=manual/src/main/java/org/qi4j/manual/recipes/assemble/Docs.java |
| tag=indirect |
| ----------- |
| |
| where it will first map the Person to a reachable PersonEntity. |
| The algorithm is as follows; |
| |
| * Look in the callers Module, if there is one and only one Composite type matching, use it. If there are two or more |
| Composite types matching, then throw an ambiguity exception. If there are zero, proceed to the next step. |
| |
| * Look in all Modules in the callers Layer. If there is one and only one Composite type that matches and is either |
| Visibility.layer, then use it. If there are two or more Composite types matching, then throw an ambiguity |
| exception. If there are zero, proceed to the next step. |
| |
| * Look in all Layers that caller's Layer uses. If there is one and only one Composite type that matches and is |
| either Visibility.application, then use it. If there are two or more Composite types matching, then throw an |
| ambiguity exception. If there are zero, proceed to the next step. |
| |
| * Throw a CompositeNotFoundException. |
| |
| The underlying principle comes down to Rickard's "Speaker Analogy", you can hear him (and not the other speakers at the |
| conference) because you are in the same room. I.e. if something is really close by, it is very likely that this is what |
| we want to use, and then the search expands outwards. |
| |
| == Combining The Above == |
| |
| Ok, that was a whole lot of theory and probably take you more than one read-through to fully get into your veins (slow |
| acting addiction). |
| How to structure your code is beyond the scope of this section. If you are an experienced designer, you will have done |
| that before, and you may have started out with good intentions at times only to find yourself in a spaghetti swamp |
| later, or perhaps in the also famous "Clear as Clay" or "Ball (bowl?) of Mud". Either way, you need to draw on your |
| experience and come up with good structure that Zest™ lets you enforce. |
| |
| So, for the sake of education, we are going to look at an application that consists of many layers, each with a few |
| modules. See picture below. |
| |
| Image of Example of Layers |
| |
| Figure 1. Example of Layers |
| |
| So, lets see how we code up this bit in the actual code first. |
| |
| [snippet,java] |
| ----------- |
| source=manual/src/main/java/org/qi4j/manual/recipes/assemble/Main.java |
| tag=main |
| ----------- |
| |
| The above is the basic setup on how to structure a real-world applicaton, unless you intend to mess with the |
| implementations of various Zest™ systems (yes there are hooks for that too), but that is definitely beyond the scope of |
| this tutorial. |
| |
| Now, the createXyzLayer() methods were excluded to keep the sample crisp and easy to follow. Let's take a look at what |
| it could be to create the Domain Layer. |
| |
| [snippet,java] |
| ----------- |
| source=manual/src/main/java/org/qi4j/manual/recipes/assemble/Main.java |
| tag=domainLayer |
| ----------- |
| |
| We just call the layerAssembly() method, which will return either an existing Layer with that name or create a new one |
| if one doesn't already exist, and then delegate to methods for creating the ModuleAssembly instances. In those method |
| we need to declare which Composites, Entities, Services and Objects that is in each Module. |
| |
| [snippet,java] |
| ----------- |
| source=manual/src/main/java/org/qi4j/manual/recipes/assemble/Main.java |
| tag=accountModule |
| ----------- |
| |
| We also need to handle the shutdown case, so in the main() method we have a installShutdownHook() method call. It is |
| actually very, very simple; |
| |
| [snippet,java] |
| ----------- |
| source=manual/src/main/java/org/qi4j/manual/recipes/assemble/Main.java |
| tag=shutdown |
| ----------- |
| |
| This concludes this tutorial. We have looked how to get the initial Zest™ runtime going, how to declare the assembly |
| for application model creation and finally the activation of the model itself. |