Incremental Testing of Adaptive Software

1 downloads 0 Views 227KB Size Report
Nov 29, 1994 - Adaptive software describes an object-oriented programming model ... Keywords: Object-Oriented Software Engineering, Software Testing, ...
Incremental Testing of Adaptive Software Linda M. Keszenheimer and Karl J. Lieberherr [email protected], [email protected] c 1994 by the authors. All rights reserved. Copyright November 29, 1994 Abstract Class evolution can have signi cant impact on the maintenance and testing of an object-oriented application. Adaptive software describes an object-oriented programming model where programs are implemented with the intent of being exible to changes in class structure. A software component is implemented and debugged based on a generic class structure, and subsequently customized in many programs with speci c class structures. Each time an adaptive component is customized with a speci c class structure, the issue of how to test the customization occurs. This paper presents a model for incrementally testing adaptive software during customization, based on initial testing with a representative class structure.

Keywords: Object-Oriented Software Engineering, Software Testing, Software Maintenance, Adaptive Software, Patterns, Class Evolution.

1 Introduction Object-oriented software engineering is being increasingly used for system development, primarily due to advantages gained from reusable components. The majority of research and literature on object-oriented software engineering has focused on analysis, design and implementation; whereas research and experience in maintenance and testing is comparatively lagging. While reuse of components is an assumed bene t of object-oriented software, it is vital that a component be well tested before it is reused. Although a well tested component will still require testing in its new environment, it is desirable to minimize this e ort. Class evolution has signi cant impact on the maintenance and testing of an application. While class evolution has been well researched, the focus has been on maintaining the structural consistency of objects existing in 1

a database. The impact of class adaptation on maintenance and testing of behavior remains to be analyzed. Adaptive software [10], [16] refers to a model of software development in which program components are designed to be exible to changes in class structure. Behavior is implemented based on a set of constraints that de ne minimal requirements of class structure. The class constraints de ne a language of compatible customizers , which are speci c class designs. An adaptive component can subsequently be tted into many customizers, thus allowing algorithmic reuse. The adaptive software model has been implemented in Demeter System/C++, a CASE tool for developing object-oriented applications. Each time an adaptive component is customized by a speci c class structure, the issue of how to test the customization occurs. This paper presents a model for incrementally testing adaptive software during customization, based on initial testing with a representative class structure. The representative class structure used for initial testing is the minimal class structure that can adequately unit test the component. When the adaptive component is customized with a speci c class structure, the potential program-based errors which may be introduced can be statically checked. The e ort of testing the customization is largely reduced by the initial testing performed on the representative class structure. The organization of this paper is the following. Section 2 provides an introduction to adaptive software, describing the model for de ning class structure and behavior. Section 3 de nes the process for testing adaptive software. Section 4 details related work in testing object-oriented programs during class evolution. Finally, section 5 concludes with future research.

2 Adaptive Software Object-oriented programs are typically developed based on a speci c class structure. A programmer designs a class by specifying its attributes and relations to other classes. Behavior is implemented by attaching functions or methods to the class structure. It is often necessary to have several classes collaborate on a particular task. This is implemented through message passing, where a message is sent along a speci c relation between classes. The class design becomes hard-wired into the methods, using speci c relations among the classes to implement collaboration. When it is necessary to adapt the class structure, the maintainer must modify existing methods to refer to the relations of the new class structure. 2

It is not a trivial task to understand the structure of object-oriented applications [15]. Object-oriented programs tend to consist of large numbers of small methods, with many methods simply propagating a request to another class, potentially passing objects through argument parameters. The program maintainer has to trace potentially long chains of calling and data ow relations. It can be dicult to understand the control and dependence between methods due to dynamic binding, as well as the ow and dependence of objects through method calls. Adaptive software alleviates many of the program understanding and maintenance problems that arise during class evolution. Behavior is de ned in a manner that places minimal assumptions on class structure. The separation of structural de nition from behavioral de nition helps elevate maintainability during structural evolution. The speci cation of a particular task is separated into several components. One component will specify the classes and relations used to collaborate on the task (a propagation graph), another component describes the ow of objects into and out of methods during the collaboration (transportation graphs) and other components (code fragments) describe task speci c behavior aside from the propagation and transportation behavior. Each of these components can be developed and tested separately, and subsequently reused in many di erent tasks. Figure 1 shows the layered architecture of adaptive software components.

2.1 Representing Class Structure The representation used in this paper is based on the Demeter data model[7]. Object structure is described in an Object Graph , where vertices represent objects and edges represent relations between objects. A Class Dictionary Graph describes a speci c class structure, with vertices representing abstract and concrete classes,

and edges representing subclass and part-of relations. A class dictionary graph may be instantiated with many object graphs, and a single object graph may be used to instantiate many class dictionary graphs. Test cases containing object graphs, or their textual equivalent, will be used to test programs. Figure 2 contains two class dictionary graphs and a template graph. A class dictionary graph is considered legal if the inheritance hierarchy is acyclic and if all direct and inherited parts of a class are uniquely labeled and ordered. To simplify the formulas in this paper, single inheritance is assumed. A template graph is used to de ne a set of legal class dictionary graphs for a given software component. The template graph in Figure 2 describes a set of minimalassumptions on class structure for a product ordering system. 3

Task Specification Propagation Patterns

Structural Specification

Object Flow Specification

Transportation Patterns Y 0/n

Y

Y

0/n

Y

Y x001

Y 0/n

XList

Y

x001 Y

Y

Y

Y

XList

rest

x001 XEList

XNEList

Y

XList

Y

Y

XEList rest

Template Graphs

XEList

XNEList

Path Specification

Y

Graph Directives Y Y x001 x001

XList

Y Y

XList

x001

rest x001

XList

rest

XEList

XNEList

XList XNEList

rest

Y rest

x001

XNEList Y XEList

XNEList XList

Y

x001

Y x001

XList

rest x001

XList

Y XNEList

XEList

rest

Y

XList

x001

rest

XNEList x001

XNEList

XEList

XEList

Customization

XList

rest XList XNEList

Class Dictionary Graphs

XEList

rest rest XNEList

XNEList

XEList

XEList

Instantiation Object Graphs

Figure 1: Layered architecture of adaptive software. The template graph describes a set of generic relations between companies, orders, products and customers. A company has many orders placed for products. Each order has associated products and customers. When an order is placed, it is initially un lled and has a due date. When the order is eventually delivered to the customer, it is considered lled. Every product has a code, and each customer has a name. The class dictionary graphs in Figure 2 de ne two speci c class designs that are legal customizations of the template graph. There are several types of vertices and edges in a class dictionary graph. A terminal vertex , drawn as ( ), represents an elementary data structure such as an Ident , String or Real . A construction vertex represents a concrete class, also drawn as (

). The representative class dictionary graph in Figure 2 has construction

vertices Company , Order , Product , Customer , Filled , UnFilled and Date . An alternation vertex (

) represents

an abstract class. FilledStatus is the only alternation vertex in the representative class dictionary graph. A repetition vertex (

) represents a collection class such as a list. The representative class dictionary graph has

three repetition vertices: OrderList , ProductList , and CustomerList . l ) with label l . A construction edge describes the part-of relation and is drawn as a single-line arrow (?!

4

Company

Product code 5 Ident

depts 1

SalesPerson List

3

filledStatus 4

PickUp

Filled

Ident

UnFilled due 7

Order

products 2

Customer name 6

2

OrderList

OrderList

FilledStatus

SalesPerson orders

orders 1

Order 2

Company

Company

1

Product List

Date

3 customer

filledStatus 4 FilledStatus

LineItem List

Customer List

product 6

Customer

code 8

Ident

Template Graph

FilledStatus

Ident

Product Date

Number

Filled

UnFilled due

Ident

Representative Class Dictionary Graph

Delivery filledStatus

9 7 quantity name

due 7

name 6

Ident

UnFilled

5

Customer

LineItem Filled

Product code 5

items Order 3 customer 4

Customizer

10

Date

Figure 2: Example class structures. l w indicates class v has a relation, or part, labeled l to class w . The construction Construction edge v ?!

edges in the representative class dictionary graph are Company orders ?! OrderList, Order products ?! ProductList, Order customer ?! CustomerList, Order

filledStatus

?!

code Ident, Customer name FilledStatus, Product ?! ?! Ident, and

date Date. The construction edges in a class dictionary graph are uniquely ordered. UnFilled ?!

An alternation edge represents the subclass relation, drawn as a double-line arrow (=) ). Alternation edge v =) w indicates v is a superclass of w . Only alternation vertices may have outgoing alternation edges. There are two alternation edges in the representative class dictionary graph, FilledStatus =) Filled and FilledStatus =) UnFilled. The re exive transitive closure of the EA relation is called the alternation-reachable relation, drawn as + )? . If v )? w, then w is reachable from v through a path of zero or more alternation edges, while v ) w implies

v )? w and v 6= w. Finally, a repetition edge v ?! w indicates v is a list containing instances of w. There are three repetition edges in the representative class dictionary graph, OrderList ?! Order, ProductList ?! Product and CustomerList ?! Customer.

De nition 1 A Class Dictionary Graph ? is a directed graph de ned as: ? = (V; ; E; Ord) where:  V = VC [VA[VR[VT  VC is a nite set of construction vertices VA is a nite set of alternation vertices

5

VR is a nite set of repetition vertices VT is a nite set of terminal vertices

  is a nite set of edge labels.  E = EC [ EA [ ER  EC is a relation on (V C [ V A)  V   describing the labeled construction edges. EA is a relation on V A  (V C [ V A) describing the alternation edges.

ER is a relation on V R  V describing repetition edges.

 Ord : EC ! N is a function that maps each construction edge to a natural number. Behavior is de ned in an adaptive program by a set of Propagation Patterns [8]. A single propagation pattern describes the collaboration and object ow required to implement a particular task. Propagation patterns can be integrated and reused in many programs. A propagation pattern is developed based on a generic class structure. To actually test a propagation pattern, it must be customized with a speci c class dictionary graph. This allows test cases containing actual object graphs to be developed. The behavior speci ed by the propagation pattern is adapted to t onto the class dictionary graph and code is generated to implement the behavior. After adequate testing using coverage measures based on the customized propagation pattern, the programmer may feel con dent that the propagation pattern has been properly debugged. An issue develops when the propagation pattern is customized by another class dictionary graph, which occurs either when the propagation pattern is used in a di erent program, or when the class structure of a program evolves. When a propagation pattern is tested and debugged with one customizer, there are no assurances that it will work correctly with another. With no restrictions on the structure of customizers, adequate testing coverage of one customizer does not imply adequacy of another. To solve this issue of testing adaptive software, it is necessary to de ne a Template Graph for a set of propagation patterns. This paper introduces the template graph, which speci es a set of class constraints that de ne the legal customizers for a propagation pattern. To reason about a propagation pattern before it has been customized, a representative class dictionary graph is generated from the template graph to be used for testing and debugging.

6

The representative is a minimal class dictionary graph adequate to fully unit test a propagation pattern. The propagation pattern can subsequently be customized by an in nite number of class dictionary graphs that meet the constraints de ned in the template graph. This is in the same fashion as schema and view integration in database applications, where components are developed separately using minimal views of a database, and then integrated and reused in multiple applications [1], [13]. Testing a propagation pattern during customization occurs in an incremental fashion. The majority of errors can be being found using the representative class dictionary graph. As in a class dictionary graph, a template graph contains construction, alternation and terminal vertices as well as construction and alternation edges. There is an additional edge not found in the class dictionary graph

called a template edge . Template edge v ; w indicates class v has a relation to class w . The template graph in Figure 2 has three template edges, Company ; Order, Order ; Product, Order ; Customer.

De nition 2 A Template Graph is a directed graph de ned as: = (V; ; E; Ord) where:  V = V C [ V A [ V T , are de ned as in a class dictionary graph   is a nite set of edge labels.  E = EC [ EA [ ET  EC is a relation on (V C [ V A)  V   describing the labeled construction edges. EA is a relation on V A  (V C [ V A) describing the alternation edges. ET is a relation on (V C [ V A)  V describing the template edges.

 Ord : (EC [ ET) ! N is a function that maps each construction and template edge to a natural number. Template edge v ; w implies a construction edge, a repetition edge, a path (sequence of construction, alternation and repetition edges), or multiple paths between vertices v and w must exist in all legal customizers. The edges in the path must not pass through other vertices contained in the template graph, and must contain at least one construction or repetition edge. A template edge allows algorithms to be written assuming a relation exists between the classes, yet the details of the relation are delayed until customization. Similarly, alternation 7

edge v =) w in a template graph may be replaced in a customizer with a path of alternation edges between v and w . A construction vertex in the template graph can be represented by an alternation vertex with subclasses in the customizer. The ordering of parts (construction and template edges) for a construction vertex v in the template graph must be preserved in the customizer. The Ord function is important since edges for a vertex are traversed in a propagation graph in a speci c order. Figure 2 contains the representative class dictionary graph for describing the product ordering data model. This class dictionary graph is generated from the template graph to serve as a representative class structure used for testing and debugging. The transformation rules for generating the representative class dictionary graph from a template graph are simple to automate, in that each template edge is transformed into a path containing a repetition class. This allows the generic relation in the template graph to be tested with zero or more instances of the target class. A speci c customizer can replace the template edge with any legal sequence of edges. Behavior will be developed and tested using the representative class dictionary graph and subsequent customization can occur with an in nite number of possible class designs, including the customizer shown in Figure 2. Let source(e) and target(e) be two functions which return respectively the source or target vertex for an edge in the graph. To simplify formulas it is assumed that class dictionary graphs have been attened, meaning inherited construction edges are distributed down to subclasses.

De nition 3 A class dictionary graph ? = (V?; ?; E?) is a legal customizer of a template graph

= (V ;  ; E ) i :

 V A  V A? ; V T  V T? Each alternation and terminal vertex in the template graph must exist in the customizer.

 8v 2 V C : v 2 (V A? [ V C? [ V R?) Each construction vertex in the template graph must exist in the customizer as either a construction, alternation or repetition vertex.

 EC  EC? Each construction edge in the template graph must exist in the customizer.

8

+  8(v ) w) 2 EA : v ) w2?

If w is a direct subclass of v in the template graph, w must be a direct or indirect subclass of v in the customizer.

 8(v ; w) 2 ET : 9 a path p = e0 e1 : : :en 2 ? where :

{ source(e0 ) = v, target(en ) = w There exists a path of edges from v to w in the customizer.

{ 9i : 0  i  n : ei 2 (EC? [ ER?) The path must contain at least one construction or repetition edge.

{ 8i : 1  i < n : target(ei ) 62 (V ) The edges in the path must not pass through other vertices in the template graph.

 8ei ; ej 2 (EC [ ET ) such that source(ei ) = source(ej ): if Ord (ei ) < Ord (ej ) then Ord?(ei ) < Ord?(ej ) The ordering of parts for a vertex in the template graph must be preserved in the customizer.

2.2 Representing Behavior In an object-oriented program, behavior is attached to a particular class. Classes often collaborate to implement a task, requiring the propagation of messages and requests along chains of class relations. Objects are often passed as argument parameters during message propagation. Code designed to propagate a message request along a path of class relations can be time consuming to produce and dicult to maintain as class structure evolves. Certain communication paths among classes tend to be reused often, with di erent tasks attaching behavior to various classes along those paths. It is useful to de ne traversal paths among classes and augment them with task speci c code. An adaptive program implements behavior by specifying subgraphs of a class dictionary graph used for collaboration and object ow. A Graph Directive is a speci cation used to describe a subgraph of a template graph or a class dictionary graph, as is shown in Figure 3. A graph directive will specify a source and one or more target vertices, and may specify intermediate vertices and edges to be included or excluded in the subgraph.

9

Graph Directive

SubGraph

Template Graph

Company

Company

FROM Company TO Product

applied to

=

Order

Product code Ident

Customer

Order

Product

name Ident

Figure 3: Applying a graph directive to a template graph. A Propagation Pattern speci es the class collaboration and object ow required to implement a task. They provide a necessary level of abstraction when implementing object behavior to facilitate class evolution [3],[5]. A propagation pattern implements an algorithm based on a generic class structure, and can be customized with speci c class structures in many programs. A propagation pattern consists of a signature, traversal directive, transportation patterns, and code fragments. A Signature speci es the function name, return type and formal arguments. A Traversal Directive speci es a graph directive to be applied to the template graph to de ne a Propagation Graph , which indicates the collaborating classes and relations used to implement the task. A Transportation Pattern describes the ow of an object along the propagation graph, or a subgraph of it. When

one class makes a request of another, it often needs to send information along with the request, or receive information back from the request. A transportation pattern describes object ow by specifying a graph directive to de ne a Transportation Graph . Finally, a Code Fragment describes task-speci c behavior aside from the traversal and transportation behavior. Figure 4 contains several simple propagation patterns for printing information for overdue orders, as well as a template graph de ning constraints for the propagation patterns and graph directives to be used to compute subgraphs of the template graph. Figure 5 shows the propagation and transportation graphs, based on the representative class dictionary graph, and an example of generated C++ code [16] for the overDue propagation pattern. The propagation graph for the overDue propagation pattern is from Company to UnFilled , indicating traversal from each Company object to each UnFilled object within an Order object. The code fragment for UnFilled orders speci es that if today's date is past the due date, then order information will be printed out.

This requires calls to the other propagation patterns, printCust and printProd . The overDue propagation pattern 10

TEMPLATE GRAPH

OPERATION void overDue() TRAVERSE CtoU CARRY IN Order* o=(@this@) ALONG OtoU WRAPPER UnFilled PREFIX (@ if ((*due) < today()) { o−>printCust(); o−>printProd(); due−>g_print(); } @)

CLASSES: Company, Order, Product, Customer, FilledStatus, Filled, Unfilled, Date, Ident EDGES ~>Company, Order //template ~>Order, Product //template ~>Order, Customer //template −>Order, FilledStatus, filledStatus //construction =>FilledStatus, Filled //alternation =>FilledStatus, UnFilled //alternation −>Product, Ident, code //construction −>Customer, Ident, name //construction −>UnFilled, Date, due //construction

OPERATION void printCust() TRAVERSE OtoC WRAPPER Customer PREFIX (@ this−>g_print(); @) OPERATION void printProd() TRAVERSE OtoP WRAPPER Product PREFIX (@ this−>g_print(); @)

DIRECTIVES CtoU= FROM Company TO UnFilled OtoU= FROM Order TO UnFilled OtoP= FROM Order TO Product OtoC = FROM Order TO Customer

Figure 4: Template graph and propagation patterns for printing overdue orders

void Company::overDue() { orders−>overDue(); }

Company orders

void OrderList::overDue() { Order_list_iterator next_Order(*this); Order* each_order; while (each_order = next_Order()) each_order−>overDue(); }

OrderList Order filledStatus

Order

FilledStatus

filledStatus FilledStatus

UnFilled

void Order::overDue() { Order* o = this; filled−>overDue(o); }

UnFilled

Propagation Graph

Transportation Graph

OPERATION void overDue() TRAVERSE CtoU CARRY IN Order* o=(@this@) ALONG OtoU WRAPPER UnFilled PREFIX (@ if ((*due) < today()) { o−>printCust(); o−>printProd(); due−>g_print(); } @)

//virtual void FilledStatus::overDue(Order* o) { } void UnFilled::overDue(Order* o) { if ((*due) < today()) { o−>printCust(); o−>printProd(); due−>g_print(); } Generated Code

Propagation Pattern

Figure 5: Propagation and transportation graphs with generated code

11

has one transportation pattern, which carries an Order object referenced by variable o from the Order vertex to the UnFilled vertex. This allows code in the UnFilled vertex to further propagate messages to the Order object. The other two propagation patterns, printCust and printProd simply traverse from the Order vertex respectively to the Customer and Product vertices, printing information. The propagation patterns are developed based on the class constraints de ned by the template graph in Figure 4, which is a textual description of the template graph of Figure 2. While this example shows all three propagation patterns using the same template graph, it also could have used three separate template graphs, each containing the constraints relevant to a single propagation pattern. Propagation patterns can be tested and debugged before being customized by using the representative class dictionary graph generated from the template graph. To ensure adequate testing, coverage is performed based on control ow, control dependence, data ow and data dependence of the propagation pattern customized by the representative class dictionary graph. The signature of a propagation pattern speci es the function name, return type, formal arguments and an optional expression to initialize the return value. It can be described in a textual form (keywords are uppercased) as: OPERATION returnType functionName()

[ INIT (@ expression @) ]

A traversal directive de nes a propagation graph, and is described in a textual form as: TRAVERSE D

Where D is the name of a graph directive. A graph directive speci es constraints that de ne a subgraph of a template graph or a class dictionary graph, and has the textual form: FROM class [ THROUGH edge-patterns ] [ BYPASSING edge-patterns ] [ VIA class-set ] [ TO class-set ]

The Transportation Pattern TP de nes the transportation of an object during traversal, and is described in a textual form as : CARRY I T n = (@ e1 @) ALONG D AT V n = (@ e2 @)

12

Where I indicates the direction an object ows along the transportation graph: IN , OUT or INOUT . T de nes the type of the object, n is a variable used to reference the object, and e1 is an optional expression for variable initialization. D is a graph directive that de nes the transportation path along which the object will be transported. It is possible to reassign the value of variable n at vertices along the transportation graph. V refers to a vertex in the transportation graph, and e2 is an expression that n should be assigned to at V . Flowing IN indicates the transported object is passed into vertices during traversal. Flowing OUT indicates the variable n is carried out of vertices during traversal. Flowing INOUT indicates the transported object is passed into and out of vertices during traversal. Transportation is implemented by extending the signature of vertices along the transportation graph to include additional formal parameters. The transported objects are passed into and out of methods through the argument parameters. Code fragments specify task-speci c behavior, aside from traversal and transportation, and are represented in a textual form as: WRAPPER VE PREFIX (@ C++ statements @) SUFFIX (@ C++ statements @)

A PREFIX wrapper indicates code to be be performed before any traversal behavior for vertex or edge VE , SUFFIX wrappers indicate code to be performed after traversal behavior.

3 Testing Adaptive Software Traditional software testing is performed in several phases, namely unit testing , integration testing and system testing . Tests are either speci cation-based (black box) or program-based (white box). For procedural programs,

unit testing refers to testing a speci c procedure, while integration testing implies testing the dependencies and interactions between several procedures. System testing involves testing the complete integration. Most models of testing object-oriented programs de ne unit testing as testing an individual class and its methods (intra-class testing). In reality this entails a combination of unit testing (individual class methods) and integration testing (interactions between methods of a single class). Object-oriented integration testing is considered to be testing class collaboration and method calls between classes (inter-class testing). 13

Adaptive software is developed and tested in several phases. Unit testing refers to the testing of an individual propagation pattern (intra-propagation pattern testing), while integration testing involves testing the interactions between several propagation patterns (inter-propagation pattern testing). Integration is performed at many levels, with integrated components potentially being further integrated into many programs. Propagation patterns are initially unit and integration tested using the representative class dictionary graph. Customization may require additional integration testing, but unit testing for a customizer is minimal.

3.1 Unit Testing a Propagation Pattern The code generated [16] by customizing a propagation pattern with the representative class dictionary graph will be represented in a Uni ed class dictionary graph [4]. The uni ed class dictionary graph is used to depict control ow, control dependence, data ow and data dependence of object-oriented programs. Test case adequacy can be assessed using various coverage measures, which are developed by computing possible paths in the uni ed class dictionary graph. The uni ed class dictionary graph consists of several layers of subgraphs, each serving a particular purpose in the testing process. The rst layer contains a class dictionary graph describing class structure, built above it in the next layer is a Behavioral Class Dictionary Graph , providing a graphical representation of behavior. The vertices in the behavioral class dictionary graph represent class methods, the expressions they contain, and the variables the expressions work on. The graph depicts the control ow of expressions in a method, and call edges show inter-method dependencies. Polymorphic calls are depicted with dynamic call edges. The behavioral class dictionary graph can easily be augmented to show control dependence and data dependence. Figure 6 contains the behavioral class dictionary graph for the overDue propagation pattern. Test cases will be built to cover the di erent paths in the graph, including the dynamic call edge. The layer above a behavioral class dictionary graph is called an Intermethod Flow Graph and shows the ow of objects during method calls. This layer denotes the ow and dependence of objects through parameters, method host objects, object sub-state, and method returns. The graph is used to compute test case adequacy for data ow and dependence. Test cases exercise the paths between de nitions and uses of variables across method boundaries. An important distinction between the intermethod ow graph and traditional data ow representations is the ability to address polymorphism and dynamic binding across method boundaries, and the 14

Company::overDue

ClassName

Order::overDue

L

ClassName

Alternation Vertex

MethodID

Method Vertex

o E1

Entry

Exit

Exit

Order

Entry

D E1 orders

E6 =

D E6

FilledStatus::overDue

E7

D

S

E7 o

E7 E6 this filled

o

= ID

ID

While

UnFilled::overDue

L

Order_list Order _iterator

Entry

ID

F 1 o

each

next

ID

Order

OrderList::overDue

L

MethodID

F 1 o

A

Exit Entry

Construction Vertex

If

Virtual Method Vertex Assignment Expression Vertex Message Expression Vertex

While Conditional Expression Vertex If Conditional Expression Vertex

Expr.ID

Order

name

Exit

Term Vertex Call Edge

E2 ? While T

D

? E5

E3 = S E4

D

E5 each

Order_list_Iterator::operator()

T

E9

D

E3 each E4 next

E8 IF

D

E11

E12

D

D

D

E10 o

E11 o

Dynamic Call Edge Control Flow Edge Destination Edge Source Edge

D S

A

E9 due

E10

E12 due

A

E9

F

Acutal Parameter Edge

ord

Formal Parameter Edge

label

today()

Date::operator