Binding to Crosscutting Themes


A Theme/UML-based design for a system is likely to be made up of multiple base and multiple crosscutting themes. Up to now, we've looked at specifying how base themes should be composed. Here, we address composing crosscutting themes with your base themes.

The principles behind composing a crosscutting theme with a base theme are based on the principles of merge integration we've already met. Assuming merge integration, this section describes additional facilities within Theme/UML for binding real elements from a base theme to the templates defined in a crosscutting theme. Recall how the templates in the design of a crosscutting theme look with the example in Figure 6-23. This shows us the track-energy theme from the game, as also illustrated in Chapter 5.

Figure 6-23. Track-energy templates.


As you can see, there are three sets of crosscutting behavior here, as indicated by three sets of templates in < > brackets. For the first, we need to identify base operations to match moveLocation(..); for the second, base operations to match energyAction(..); and for the third, base operations to match joinGame(..). In order to figure out what operations should match, you'll probably find it useful to go back to the Theme/Doc views of the requirements to see where the track-energy theme crosscut other themes and also to look at those crosscutting theme views and their corresponding

Theme/UML designs. From the requirements and Theme/Doc views, energy is depleted at different rates depending on whether or not the player is in a game location. This behavior can be triggered each time a new location is registered, as designed in the enter-location theme. This is achieved with the setLocation() operation in the Player class, as illustrated in the Theme/UML design from Chapter 5. There is no other place in the game design that registers a change in location. The Theme/Doc views illustrate more instances of actions that trigger a change in energy levels: when a player gets crystals and also when a player completes some NPC-assigned tasks, for example a physical test. From the Theme/UML designs, the operations that denote a player obtaining crystals are in Player.incrementCrystals from the enter-location theme and Player.addCrystals(int) from the duel theme. We did not include Theme/UML designs for completing tasks from NPCs, but we can assume here that the operations Player.completeWizardErrand() and Player.completeWarriorTest() indicate when these actions are completed. Finally, from the Theme/UML designs, the operation that denotes a player joining a game is Player.joinGame().

Now that you've identified the operations that will bind to the templates in the track-energy theme, it's time to indicate this with a composition relationship and a bind[ ] tag. For each set of templates denoting different sequences of behavior within the < > brackets, you may define one or more "real" elements to bind to those templates, also in matching < > brackets. As illustrated in Figure 6-24, the first < > bracket has just a single real operation to indicate a move in location, while the second < > bracket includes a set of operations that correspond to an action requiring a change in energy. Note that where there is more than one real operation to be bound to the template, the set of operations is bound in { } brackets. We also compose with the game theme that is the result of the composition specified in Figure 6-16. Indeed, we advise you to compose base themes first, and then compose with crosscutting themes. We should also point out an important rule hereonly one crosscutting theme may be composed at a time. This forces you to consider the ordering of execution of multiple crosscutting behaviors, thereby reducing the potential for conflict.

Figure 6-24. Binding to the track-energy crosscutting theme.


Adding a bind[] attachment to the composition relationship has the effect that a sequence diagram is generated for each of the replacing operations. Each generated sequence diagram indicates how the crosscutting behavior impacts the replacing operation. In addition, there are now two operations in the design for each of the replacing operations. One is an operation of the same name as the replacing operation. This operation triggers all behavior, as defined in the sequence diagram. The second operation is the real operation renamed with a prepended _do_ to indicate the original behavior.

For the remaining elements in the crosscutting theme and the base theme, elements are merged as described previously. When a crosscutting theme is being composed, a match[name] tag is assumed, which means that elements with the same name will be matched and merged. In the track-energy theme (refer to Figure 5-21), there is a class called Game, which will be merged with the Game class in the game theme.

Let's look at another examplethe P2PCommunications crosscutting theme. Recall the template specification from the Theme/UML design from Chapter 5, as copied here in Figure 6-25. As you can see, there are four different sequences of crosscutting behavior: when a player joins a game, when a player's state changes, when a location's state changes, and when the game application starts.

Figure 6-25. P2PCommunication templates.


As you can see in Figure 6-26, one operation, Player.join(..), replaces the TPlayer.joinGame(..) template. In addition, state of interest for locations relates to the crystals they have, and state of interest for players relates to the crystals and magic items they have. By replacing the templates with methods that effect these states, we say that the relevant crosscutting behavior should also occur. Notice that we specify the composition relationship with the composed game theme and corresponding composed Player and Location classes. As before, the other elements in both themes are merged, with elements matched by name. This has the effect that the GameAdmin, Game, Player, and Location classes in the P2PCommunication theme illustrated in Figure 5-25 will be merged with the classes of the same name in the game theme. Since Player, Location, and GamesAdmin have the methods that replace the templates, then this, in effect, means that the crosscutting behavior is also merged with the matching classes.

Figure 6-26. Binding to the P2PCommunication crosscutting theme.


In all of the examples of crosscutting behavior in our game, there is only one template for each sequence of behavior defined in a sequence diagram. Of course, this may not always be the case. There is no limit to the number of templates that can be specified within a single sequence of behavior. However, there is one important rule here: the first template in the < > sequence group in the template box must represent the replacing operation that triggers the sequence of behavior. Correspondingly, the first replacing operation in the bind[] attachment will be the one that triggers the behavior.

The Observer design pattern is a good example of when more than one template is required within a single sequence of events. In the Observer pattern, there are subjects and observers. Observers register an interest in being notified of changes in state in subjects. When a change in state happens in the subject (sounds like a good Theme/UML template!), an event is sent to observers (again, another good template!). Figure 6-27 illustrates the template box of an observer crosscutting-theme design that includes templates for three sequences of behavior. Crosscutting behavior is also illustrated for changes in state in the subject. There is also crosscutting behavior in the observer theme for when an observer initiates or terminates its interest in a subject, which is not illustrated.

Figure 6-27. Observer templates.


As you can see, the state change sequence of behavior has two templates, aStateChange(..) and update(), and a single sequence diagram captures the combination of behaviors. This brings us to a refinement of a statement made previously: we said that a sequence diagram is generated for each replacing operation in a composed design. We now need to clarify this and state that a sequence diagram is generated for each set of replacing operations related by a single sequence of behavior (i.e., for groupings within < > brackets in the template box).

Let's look at the simple case where we have instances of a Location class (subjects) being observed by instances of a Player class (observers). In particular, the state-change operation (takeCrystals()) in Location is observed by the Player, who is to be notified using the crystalsTouched() operation. In this case, the bind[] attachment on the composition relationship between the observer theme, and the game theme would be[6]

[6] We do not illustrate the binding to the other two sequences initiated by start() and stop(), as these are the simple case, and specifying their bindings has the same syntax as the previous examples from the game.

 bind[ < Location.takeCrystals(),         Player.crystalsTouched() >       < .. >       < .. > ]  

In this example, a single sequence diagram is generated that sends a crystalsTouched() event to an instance of the Player class when the instance of the Location class it has expressed interest in executes takeCrystals().

What if there are multiple state changes to be observed? The { } bracketing can be used here to group the operations that replace a template. For example,

 bind[ < { Location.takeCrystals(),          Location.addCrystals()} ,           Player.crystalsTouched() >       < .. >       < .. > ] 

In this example, two sequence diagrams are generated to indicate what happens when takeCrystals() and addCrystals() are executed. In both cases, crystalsTouched() from the Player class is also executed. A further syntactical refinement is possible here with additional { } brackets to group operations from the same class. For example, since takeCrystals() and addCrystals() are both in the Location class, we can also group them together in that context, as follows:

 bind[ < { Location.{takeCrystals(), addCrystals()}} ,           Player.crystalsTouched() >       < .. >       < .. > ] 

In general, when multiple operations replace the first template (i.e., the template that represents triggering of the crosscutting behavior), a sequence diagram is generated for each.

What if you did not want Player.crystalsTouched() to be executed in every instance of a state change? We do not allow multiple replacements for any template following the triggering template, so in this case, you must specify the groupings explicitly. You need to specify multiple nested bindings within a < > set, with further < > sets. Let's say we want crystalsTouched() from Player to be called any time takeCrystals() or stealCrystals() is executed in Location. We also want players to observe when crystals are added to a location, but instead of calling crystalsTouched(), we want newCrystals() to be executed.

In the following example, all operations that start with add in the Location class trigger behavior that results in the execution of Player.newCrystals() (enclosed in nested <> brackets), while takeCrystals() and stealCrystals() result in the execution of Player.crystalsTouched() (also enclosed in nested <> brackets).

 bind[ < < {Location.add*()}, Player.newCrystals() >         < {Location.{takeCrystals(), stealCrystals()}},             Player.crystalsTouched() > >       < .. >       < .. > ] 

Within each <> grouping, the first template in a sequence group that triggers the crosscutting behavior may have multiple bindings, but subsequent templates may not.



Aspect-Oriented Analysis and Design(c) The Theme Approach
Aspect-Oriented Analysis and Design: The Theme Approach
ISBN: 0321246748
EAN: 2147483647
Year: 2006
Pages: 109

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net