4. Designing an Event-Driven Application

This QP-nano Tutorial is adapted from Chapter 1 of Practical UML Statecharts in C/C++, Second Edition
by Miro Samek, the founder and president of Quantum Leaps, LLC.

qp_tutorial.jpg

Prev: 3. The main() Function and the qpn_port.h Header File
Next: 5. Elaborating State Machines of Active Objects

To proceed further with the explanation of the "Fly 'n' Shoot" application, I need to step up to the design level. At this point I need to explain how the application has been decomposed into the active objects, and how these objects exchange events to collectively deliver the functionality of the "Fly 'n' Shoot" game.

In general, the decomposition of a problem into active objects is not trivial. As usual in any decomposition, your goal is to achieve possibly loose coupling among the active object components (ideally no sharing of any resources), and you also strive for minimizing the communication in terms of the frequency and size of exchanged events.

In the case of the "Fly 'n' Shoot" game, I need first to identify all objects with reactive behavior (i.e. with a state machine). I applied the simplest object-oriented technique of identifying objects, which is to pick the frequently used nouns in the problem specification. From Section 2. Let's Play, I identified Ship, Missile, Mines, and Tunnel. However, not every state machine in the system needs to be an active object (with a separate task context, an event queue, and a unique priority level), and merging them is a valid option when performance or space is needed. As an example of this idea, I ended up merging the Mines into the Tunnel active object, whereas I preserved the Mines as independent state machine components of the Tunnel active object. By doing so I applied the "Orthogonal Component" design pattern described in Chapter 5 of Practical UML Statecharts in C/C++, Second Edition.

The next step in the event-driven application design is assigning responsibilities and resources to the identified active objects. The general design strategy for avoiding sharing of resources is to encapsulate each resource inside a dedicated active object and to let that object manage the resource for the rest of the application. That way, instead of sharing the resource directly, the rest of the application shares the dedicated active object via events.

So, for example, I decided to put the Tunnel active object in charge of the display. Other active objects and state machine components, such as Ship, Missile and Mines, don't draw on the display directly, but rather send events to the Tunnel object with the request to render the Ship, Missile, or Mine bitmaps at the provided (x, y) coordinates of the display.

With some understanding of the responsibilities and resource allocations to active object I can move on to devising the various scenarios of event exchanges among the objects. Perhaps the best instrument to aid the thinking process at this stage is the UML sequence diagram, such as the diagram depicted in Figure 4-1. This particular sequence diagram shows the most common event exchange scenarios in the "Fly 'n' Shoot" game (the primary use cases, if you will). The explanation section immediately following the diagram illuminates the interesting points.

Note:
A UML sequence diagram like Figure 4-1 has two dimensions. Horizontally arranged boxes represent the various objects participating in the scenario whereas heavy boarders indicate active objects. As usual in the UML, the object name in underlined. Time flows down the page along the vertical dashed lines descending from the objects. Events are represented as horizontal arrows originating from the sending object and terminating at the receiving object. Optionally, thin rectangles around instance lines indicate focus of control.
Fig1.04.jpg

Figure 4-1 The sequence diagram of the Fly 'n' Shoot game.

Even though the sequence diagram in Figure 4-1 shows merely some selected scenarios of the "Fly 'n' Shoot" game, I hope that the explanations give you a big picture of how the application works. More importantly, you should start getting the general idea about the thinking process that goes into designing an event-driven system with active objects and events.

Prev: 3. The main() Function and the qpn_port.h Header File
Next: 5. Elaborating State Machines of Active Objects

logo_ql_TM.jpg
Copyright © 2002-2008 Quantum Leaps, LLC. All Rights Reserved.
http://www.quantum-leaps.com
Generated on Sat Dec 27 22:01:47 2008 for QP-nano by  doxygen 1.5.4