| <!-- |
| 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. |
| --> |
| <body> |
| <h1>Tutorial 4 - Concerns</h1> |
| <p> |
| In this tutorial we refactor the mixin from the previous steps so that the result of the say() method |
| is modified to be prefixed with "Simon says:". To do this we need to implement a Concern for |
| the say() method. Concerns are a type of Modifier which modify the behaviour of |
| the methods in Mixins. They do this by intercepting the invocation of the TransientComposite. This allows |
| them to change the invocation parameters, return their own values or throw their own exceptions, |
| and do other things which directly affect the invocation of the method. |
| </p> |
| <p> |
| Concerns should not perform any side-effects, such as updating state in another TransientComposite, Mixin |
| or similar. Any side-effects are done in SideEffects, which is another type of Modifier, which are |
| allowed to perform side-effects but, in contrast to Concerns, cannot change the parameters or |
| in any other way change the result of the invocation. |
| </p> |
| <p> |
| Concerns are implemented in one of two ways: either create a class which directly implements |
| the interface whose methods should be modified, or create a generic Modifier by implementing |
| the InvocationHandler interface (or subclass GenericConcern which does this for you). |
| Add an @ConcernFor dependency injection, as a field, constructor parameter or method parameter, |
| which has the same type as the interface the Concern implements. When the TransientComposite is invoked |
| the Concern will be called, allowing it to perform it's work. If the call should proceed, then |
| invoke the method again on the injected object. The preferred way to do all of this is to subclass |
| ConcernOf which does all of this for you. |
| </p> |
| <p> |
| Concerns are applied by adding an @Concerns annotation on the TransientComposite, the domain interface, |
| or the Mixin implementation. Any of these works, and where to put it is a matter of design choice. |
| </p> |
| <p> |
| Steps for this tutorial: |
| </p> |
| <ol> |
| <li>Create a typed concern, implement the HelloWorldBehaviour and let it modify the result |
| of the base method by prefix the result with "Simon says:". |
| </li> |
| <li>Add an @Concerns annotation on the HelloWorldBehaviourMixin which references the Concern class.</li> |
| </ol> |
| </body> |