Designing Crosscutting Themes


A theme is crosscutting (or an aspect) when at least some of its behavior is triggered by behavior in one or more other themes. In other words, there is behavior in the crosscutting theme that occurs only relative to the behavior in the theme(s) it crosscuts. When you're designing such a theme, you want to be able to refer to that outside behavior without explicitly naming it. Imagine a crosscutting theme that is designed to have multiple collaborating classes. The crosscut behavior (in the base theme) might occur at any stage in the collaboration between the classesindeed, at more than one stage. Theme/UML uses an extension of UML's notion of templates that lets you refer to outside elements in a parameterized way. Given that there may be multiple behaviors (within multiple classes) that may be crosscut, then a crosscutting theme may have multiple templates. These templates may be parameters for different kinds of design elements, such as classes, operations, or attributes. At composition time, the "real" elements in the theme to be crosscut replace the templates in the design. Where the template is a class, the design elements in the crosscutting theme are added to the existing elements in the real class. Where the template is an operation, execution of the real operation occurs as specified in the collaboration diagram of the crosscutting theme. Where the template is an attribute, the real attribute is used where the template is referred to in the crosscutting theme. We describe the implications at composition time in more detail in Chapter 6. Here, we look at what the designer of a crosscutting theme has to do.

Changes to the UML

Before we look at some crosscutting theme designs, let's first discuss working with templates from a notational perspective.

Crosscutting Behavior and Templates

Crosscutting behavior is triggered by the behavior it crosscuts. Standard UML has useful models for specifying collaborative behavior, which can be used in Theme/UML. In particular, you will find sequence diagrams a useful means for specifying when crosscutting behavior should occur relative to the crosscut behavior. With a sequence diagram, you can supplement the real behavior by defining other behavior in a sequence around it. In essence, what you are saying is, "When the real behavior happens, do all this other behavior as well as the real behavior." In the sequence diagram, you will refer to the real behavior with a template that, from a notational perspective, looks like every other operation call. You will distinguish it as a template separately.

Of course, the real behavior has to happen at some point, and you need some way to distinguish between the operation that replaces the template (and therefore triggers the combination of its own behavior and the crosscutting behavior) and the actual execution of the replacing operation. For the latter, add _do_ to the beginning of the operation name in the sequence diagram. This is one hint that the operation is a template in the sequence diagram. As we describe in more detail in Chapter 6, this triggers, during the composition process, a renaming of the real operation (and setting its visibility to private) so that the original operation's name can trigger all appropriate behavior defined in the sequence diagram. For example, Figure 5-14 illustrates a sequence diagram for the moveLocation(..) template of the track-energy theme. When a player moves location, she may have entered a location where the energy loss is different, which must be checked by the track-energy theme. Energy is lost at either two units or one unit every five minutes, depending on where the player is located (R37 and R41 from Theme/Doc's individual theme view). This sequence diagram specifies that after the actual move-location operation is performed (_do_moveLocation(..)), the crosscutting behavior relates to finding out whether the player's current location is in a game location and setting the amount of energy to lose to either 1 or 2 appropriately.

Figure 5-14. Crosscutting behavior notation.


Control Flow Restrictions on Triggers

In the moveLocation(..) example illustrated in Figure 5-14, any execution of real behavior that replaces the moveLocation(..) template will trigger the crosscutting behavior. In some cases, however, you may want to restrict when the real behavior becomes a trigger. In particular, you may want to say that the real behavior becomes a trigger only when it is executing within the control flow of other behavior. Again, sequence diagrams provide us with the means to express this. For example, as illustrated in Figure 5-15, crosscutting behavior is defined for an op2(..) trigger. However, it is defined within the flow of control of _do_op1(..), which means that op2(..) becomes a trigger for the crosscutting behavior before() and after() only when it occurs within _do_op1(..)'s flow of control.

Figure 5-15. Trigger within a specified flow of control.


Template Operation Parameters

You've probably noticed the ".." parameter specification of moveLocation(..) , op1(..) and op2(..) in the previous examples This indicates that an operation of any signature may replace the template. Possible parameter specifications relate to the scope within which the replacing operation is executed. For example, in Figure 5-14, the active period of the execution of moveLocation(..) defines the scope for this operation, and any parameters defined may be used within this scope. The parameter possibilities are defined in Table 5-5.

Table 5-5. Parameter Specification

Parameter

Usage

op()

The replacing operation must have no parameters.

op(..)

The replacing operation may have any signatures.

op(.., Type, ..)

The replacing operation must have a parameter of type Type in its parameter list, as it is required by the crosscutting sequence of behavior. Other than that, there may be any other parameter(s) of any type.


Listing the Templates for a Theme

UML's templates are parameterized model elements that are contained in a class that is then called a template class. These templates are ordered in a dotted box on the class box notation. In Theme/UML, a theme may have templates that are class types and therefore are placeholders to be replaced by real class elements. Here's a rule: every template operation or template attribute must be defined as part of a template class. In other words, if you have a class in your crosscutting-theme design that contains a template operation or parameter, then the class itself is also considered to be a template, and all its nontemplate elements are added to a real class at composition. This makes sense, because the replacing real operation or attribute already has a containing class, with potentially other elements that it needs or other elements that use it, and therefore should be merged with the template class. We describe this in more detail in Chapter 6, "Theme Composition."

Since template classes are contained in the crosscutting theme, Theme/UML (in the spirit of standard UML) places all the templates for the theme in a dotted box on the theme box notation. Within this box, templates are grouped by sequence diagram. The templates defined in each sequence diagram (or behavioral group) are grouped within <> brackets. There is one important rule here: the first operation in the group must be the one that triggers the crosscutting behavior. Remember we are specifying crosscutting behavior here that is triggered by behavior in a base theme. It would not make sense for the first operation of the sequence of behavior not to be the triggering operation. There may also, of course, be more templates defined within the sequence of behavior, and ordering within this group is important. These triggers may or may not be restricted by the control flow of others.

Figure 5-16 illustrates the templates for the track-energy theme. There are three behavioral groups, each with one template operation: moveLocation(..) (behavior illustrated in Figure 5-14), energy Action(..), which supports the game requirement that a player may gain some energy after performing some action, and joinGame(..), which supports the game requirement that a player periodically loses energy throughout the game.

Figure 5-16. Template notation.


There is no limit (other than common sense!) to the number of behavioral groups you can have or the number of template operations/attributes you can define within a behavioral group. There must, however, be a corresponding behavioral group of templates for every sequence diagram that uses templates in the theme. In addition, every named template within the sequence diagram must be listed in the < > list, comma-separated.

Within a single < > behavioral group, you might have a number of template operations and attributes in the same template class. For convenience, you may qualify these with a list notation {}. For example, the following template group has six template operations, three in ClassA and three in ClassB.

 < ClassA{op1(), op2(), op3()}, ClassB{op1(), op3(), op4()} > 

Don't forget that the first operation is the one that triggers the crosscutting behavior in the corresponding sequence diagramin this case, ClassA.op1(). A template class qualifies template operations and attributes, which means, for this example, that there is no conflict between ClassA.op1() and ClassB.op1().

Referencing Template Structure and Behavior

Like base themes, an aspect theme design provides a design specification for all the requirements for which it is responsible. As such, it will contain structural and behavioral models appropriate to capture that specification. Structural models will specify the classes, attributes, and relationships of the theme. At least some, but probably not all, of the behavioral models will be triggered by operations outside the theme. In the base themes, operations that trigger a sequence of crosscutting behavior are likely to appear in different classes, but the corresponding template is captured in a single template class in the aspect theme. Such a template class will have additional elements defined to capture the crosscutting behavior. As we'll describe in Chapter 6, at composition, these additional elements will be added to the triggering class. Looking forward to any possible composed design, it may have many different classes that were composed with the template class because those classes have operations that trigger the relevant crosscutting behavior.

This has implications for using the template class as a reference type within the aspect theme design. Let's say we have a class called ClassA in the aspect design that is not a template classin other words, has no crosscutting behavior to be triggered outside the aspect. We would expect ClassA, nonetheless, to be added to a composed design. Let's further say that ClassA has an attribute called att1. If we say that att1's type is a template class, which of the many possible types will it be in a composed design? It is ambiguous because there may be many classes composed with the template class. To avoid such confusion, Theme/UML does not allow external references to a template class.

The same problem also applies to invoking methods within a template class from a different class in the aspect themelet's say our ClassA again. If a method in ClassA invokes a method in a template class, which method should be executed when the aspect theme is composed with base themes? Again, it is ambiguous and to avoid confusion, Theme/UML does not allow external method invocations on a template class. Figure 5-17 summarizes what you can and can't do. In the figure, ClassB is a template class, and ClassA and ClassC are not.

Figure 5-17. Referencing template structure and behavior


These rules do not restrict you from invoking methods that you expect to be provided by a base theme. Recall the invocation of Player.duel() in the enter-location base theme. There may be many such situations where you invoke a method you expect to be in another theme, and therefore don't provide any other specification for it. What do you do in an aspect theme if that method is in a class that you expect to have a trigger for crosscutting behavior and therefore will be merged with a template class containing that crosscutting behavior? Theme/UML's rule says you can't invoke a method in a template class outside that class. However, you can still include in the aspect theme a class (such as Player from the example above) that you expect to have the behavior you need. The P2PCommunication aspect theme that we describe later in this section has good examples of how to handle adding aspect theme-specific behavior to Player that you explicitly want to be merged with the Player class from the base, while also working with triggers that are likely to come from the Player class. In Chapter 6, we describe compositions of aspect and base themes that sort out such situations.

Track-Energy Theme

Chapter 4 illustrated how the use of Theme/Doc can help you figure out which themes in the requirements crosscut other themes. One such theme is the track-energy theme, which is responsible for managing a player's energy. Requirements for the track-energy theme are listed in Table 5-6.

Table 5-6. Track Energy Requirements

R No.

Requirement Text

R21

If players do not reach their initial location within the specified time, they lose 1 energy point.

R37

Players lose energy faster while in a location: they lose two units per five-minute period.

R40

Players gain 10 units of energy when the game begins.

R41

As players proceed throughout the game, their energy dissipates by one unit for each five-minute period.

R42

Energy is gained by two units when they find a crystal upon entering a location.

R77

Completing an errand successfully provides four units of energy to the player.

R80

When players complete a physical test challenge successfully, they gain three units of energy and win a crystal.


The triggered behavior in the theme is illustrated in the individual aspect-theme view. Figure 5-18 illustrates a snippet of track-energy's individual theme view that shows the crosscutting relationships between the actions. These relationships indicate that there are three triggers expected in base themes that will have crosscutting behavior here. They map to the Theme/UML templates for the theme, as these capture the triggers that initiate crosscutting behavior. Mappings are indicated by gray shadows in the figure.

Figure 5-18. Mapping templates from individual aspect- theme view.


On to the design, when we look at the group of requirements, we see that there is a lot of game-play decision making related to how much energy is gained or lost on various activities. We make the decision to encapsulate this knowledge into a class called Game that the Energy class can use to find out the information it needs to determine how to change state.

Let's look at the lose-energy behavior node from the individual theme view snippet in Figure 5-19. This action does not have a crosscutting relationship to other behavior in the theme view, and its sequence diagram simply changes the energy amount when it's triggered, as handled in the state diagram. However, crosscutting behavior is required to change the amount of energy units that are lost every five minutes. This behavior crosscuts moving location, which gave us the template operation moveLocation(..) and its corresponding sequence diagram, as illustrated in Figure 5-14. Figure 5-19 illustrates how loss of energy works. The state machine for the Energy class specifies that after a certain number of minutes (number defined in the duration attribute), a loseEnergy() event is sent. Figure 5-19 also illustrates how the Energy class responds to the loseEnergy() eventit decrements the energyUnit attribute by the value in the changeAmount attribute. The response to the loseEnergy() event does not crosscut any other behavior. Note that it is perfectly normal in a crosscutting theme to have some behavior that is part of the responsibility of the theme that does not crosscut behavior outside the theme.

Figure 5-19. Lose energy behavior.


Figure 5-19 also illustrates some crosscutting behavior that specifies when the thread to kick off losing energy should be started. In this case, as soon as a player joins a game, energy is depleted after a specified duration. The template operation is joinGame(..), and after this has completed, the thread is started.

Figure 5-20 illustrates the behavior that crosscuts some actions in the game (denoted by the energyAction(..) template operation). The Game class is responsible for knowing the game rules regarding how much energy a player wins or loses after a particular action. These rules are defined in requirements R42, R80, R77, and R21. This design uses the name metaproperty of the energyAction(..) model element[1] to get a String representation of the name so that the Game class can tell it by how much energy to change the current value. This behavior crosscuts the particular action, which is executed beforehand, as illustrated by _do_energyAction(..)in the sequence. The changeEnergy(int) operation either increases or decreases the energy levels, depending on the guidance of the Game object. This encapsulates both the gain and lose behavior nodes from the individual theme view.

[1] In general, Theme/UML allows a designer to refer to the metaproperties of any model element (i.e., the properties defined for the particular model element construct in the UML metamodel).

Figure 5-20. Change energy after action.


As with all designs, there is likely to be a structural diagram that illustrates the structure of the classes in play in the behavior. Figure 5-21 illustrates the class structure for the track-energy theme. Notice that requirement R40 is handled structurally by setting the initial value of the energyUnit attribute to 10.

Figure 5-21. Track-energy theme structure.


There are a couple of interesting things to note here. In the Theme/Doc individual theme view snippet, there are two shadowed white object nodes (point and unit) and five shadowed gray object nodes (location, game, player, crystal, and physical test). As described in Chapter 4's, "Planning for Design" section, the white nodes indicate that the objects wholly belong to the theme. After looking at the requirements that refer to point (R41) and unit (all five other requirements), we consider them to be synonyms and map them to an attribute (energyUnit) in the Energy class. Again, the decision whether this should be a class or an attribute is a standard object-oriented oneat this stage, we don't see that unit has any interesting properties or behavior, so we make it an attribute.

The gray nodes indicate that the objects are shared with other themes. On examination of each one, we determine that Game is the only one that is useful to model for tracking energy. We need Game to tell us whether a player is in a game location and also to handle the rules related to changing a player's energy as a result of some action. We can also imagine that there is likely to be a Game class in other themes. This means that the track-energy theme is an example of a crosscutting theme that also shares concepts with other themes, which we address during composition.

Note also that the template operations and their corresponding private, renamed operations all appear in the Energy class. This makes sense because the template operation and the renamed operation each denote different behaviorone denotes the triggering of crosscutting behavior, and one denotes the real operation.

Finally, Energy is an active class because it responds to the loseEnergy() event.

P2P Communication Theme

The track-energy theme we just described was one of the crosscutting themes identified during the Theme/Doc analysis process. Of course, during detailed design of a system, you are concerned with architectural, system questions that may not directly manifest in the requirements. As a result of such detailed design, more technical kinds of behavior may crosscut the application logic. Indeed, many of the aspect examples you've seen probably describe such technical behavior. One example of crosscutting behavior that arises because of the chosen P2P architecture for the Crystal Game is the event-based communication between player peers. To handle this communication, we defined a theme called P2PCommunication.

In essence, the P2PCommunication theme monitors the game state that all players (or potential players) are interested in, gathers up (or marshals) that game state, and broadcasts or multicasts (as appropriate) an event containing it. This theme is also responsible for listening for such events and for unmarshaling the game state information for its player. Recall that we assume a total-order, atomic broadcast/multicast, so this theme may assume that for all events any player sees, every other player sees those events in the same order.

The P2PCommunication theme has a combination of behavior that directly crosscuts game-logic behavior and behavior that occurs either on receipt of an event or periodically and therefore does not directly crosscut game-logic behavior. We need to treat the design of these two (crosscutting behavior vs. noncrosscutting behavior) differently, as you'll see in how Player, Location, and GamesAdmin are handled. Taking Player as an example, we are trying to do two things here. First, we're creating behavior that we know we want to be merged with the Player class in the base. Second, we want to capture a trigger to tell us when a player changes state triggers that, coincidentally, are highly likely to come from the Player class.

As we've described previously, the crosscutting theme model allows for multiple triggers from potentially multiple different base classes. We therefore need to conform to the rules that help to avoid referencing confusion described in the section "Referencing Template Structure and Behavior." To achieve both our objectives for the Player class, we separate them by having a Player class that holds behavior we want to be merged with a base Player class, and separately having a TPlayer template class, to capture the behavior that crosscuts a trigger. This approach is also taken for the design of behavior for Location and GamesAdmin. How these are composed is sorted out later.

Two examples of crosscutting behavior are illustrated in Figure 5-22. Game state that all players are interested in relates to state associated with a location (e.g., any change to the number of crystals or magic items there) and also state associated with a player (e.g., when a player finds crystals or magic items, or duels another player, or has an encounter with an NPC).

Figure 5-22. Behavior crosscutting player and location changes.


Any changes to location or player state are of interest to every player and so need to be multicast to all the players in the game.

The lStateChange() and pStateChange() template operation sequence diagrams first indicate that the real operations are executed (with _do_lStateChange() and _do_pStateChange() (respectively), and then the location or player state is marshaled into LocationUpdate() and PlayerUpdate() events that are multicast for the attention of each player's Game object. On receipt of these events, the Game objects unmarshal the location or player information and update the corresponding objects with the new information.

Crosscutting behavior is also illustrated in Figure 5-23. When a player joins a game, he needs the complete game state and so broadcasts an event called FullGameStateRequest(gameName) intended for the attention of game objects. When a Game object receives this event, it marshals all relevant game state relating to game locations and other players, and multicasts this information in a FullGameState(state) event also intended for the attention of Game objects. When a Game object receives a FullGameState(state) event, it unmarshals and updates the player and location information.

Figure 5-23. Behavior crosscutting players joining a game


Other behavior in the P2PCommunication theme is time triggered and does not crosscut game behavior. For example, Figure 5-24 illustrates how potential players are informed of ongoing games in the region that they might be interested in joining. After a time period (currently 30 seconds), each GamesAdmin object broadcasts an event called CrystalGamesAvailable(games), containing the games it knows about, that is intended for other GamesAdmin objects. On receipt of this event, a GamesAdmin object updates the games it knows about. Figure 5-24 also illustrates some crosscutting behavior in which the thread to kick off the time-triggered behavior is started. The template operation newGamesAdmin(..) is defined to capture the instantiation of the GamesAdmin object, after which it should broadcast games it knows about.

Figure 5-24. Behavior for broadcasting game information.


Figure 5-25 illustrates the class structure for the P2PCommunication theme. As you can see, the Games and GamesAdmin classes are active classes and respond to events received. They are not template classes, though it is likely that these concepts will appear in other themes in the Crystal Game. As with the track-energy theme, you do not have to concern yourself with this nowwe sort it out at composition time. Also, note that the TPlayer class has both a pStateChange() template operation and corresponding private _do_pStateChange() operation, and also a joinGame() template operation and corresponding private _do_joinGame() operation. Also, the TLocation class has an lStateChange() template operation and corresponding private _do_lStateChange(). As before, these relate to the need to distinguish between the operation that triggers all crosscutting behavior and the execution of the replacing operation itself.

Figure 5-25. P2PCommunications theme structure.


The P2PCommunication theme has demonstrated a good range of the possibilities for specifying crosscutting themes. There are a number of templates with different behavior in play under different circumstances. In addition, there is noncrosscutting behavior related to the responsibilities of the theme. Two small capabilities of Theme/UML are not covered in either this theme or the track-energy theme. Table 5-5 illustrates three parameter specification possibilities, one of which (..) is widely used in our two example themes. This is probably the most common one you will encounter, where you are saying that the template operation can have any signature. Sometimes, however, your sequence of actions may need to use an object of some type, which is when you use the (.., Type, ..) parameter specification. In this case, the parameter of type Type is named in the sequence diagram and can be used by name by later operations. The restricted parameter specification () is included for completeness. We have not encountered a situation where you must limit the template operation to no parameters, as we expect a real operation to occur independently of any defined crosscutting behavior (or not at all, if that is what is defined in the sequence diagram).



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