Expressions Example


This example exposes some of the difficulties in making the transformation from requirements to objects. It involves the construction and evolution of a simple expression evaluation system (EES). A simplified software development process is assumed, consisting of informal requirements specification in natural language, design in UML, and implementation in Java.

The required EES supports the specification of simple expression programs. The set of tools needed to work with expressions is listed in Table 2-4.

Table 2-4. Expression Evaluation System

R No.

Requirement Text

R1

An evaluation capability that determines the result of evaluating an expression.

R2

A display capability that depicts expressions textually.

R3

A check-syntax capability that optionally determines whether expressions are syntactically and semantically correct.

R4

The check-syntax, display, and evaluation operations should all be logged.


The initial software system supports a small grammar for expressions as follows:

 Expression := VariableExpression | NumberExpression |   PlusOperator | MinusOperator | UnaryPlusOp | UnaryMinusOp PlusOperator := Expression '+' Expression MinusOperator := Expression '-' Expression UnaryPlusOp := '+' Expression UnaryMinusOp := '-' Expression VariableExpression := ('A'| 'B' | 'C' | ... | 'Z') + NumberExpression := ('0' | '1' | '2' | ... | '9') + 

This grammar basically means that an Expression is either a VariableExpression, a NumberExpression, a PlusOperator, a MinusOperator, a UnaryPlusOp, or a UnaryMinusOp. A PlusOperator is made up of two Expressions, with a + symbol between them; a MinusOperator is made up of two Expressions with a - symbol between them; and so on. The grammar for expressions can be rewritten as requirements R5 through R11, as is shown in Table 2-5.

Table 2-5. Expressions Grammar Requirements

R No.

Requirement Text

R5

Expression is defined as a variableexpression or a numberexpression or a plusoperator or a minusoperator or a unaryplusop or a unaryminusop.

R6

plusoperator is defined as an expression and a plus-operator and an expression.

R7

minusoperator is defined as an expression and a minus-operator and an expression.

R8

unaryplusop is defined as a plusoperator and an expression.

R9

unaryminusop is defined as a minusoperator and an expression.

R10

variableexpression is defined as a letter and an expression.

R11

numberexpression is defined as a number and an expression.


This grammar is very simple to effectively illustrate two problems: first, even with a small grammar, the design of a supporting EES gets unwieldy, and second, adding new constructs to the grammar, such as a product or assignment operator, requires crosscutting changes to the design.

Object-Oriented Design

The EES design represents expressions as abstract syntax trees (AST). Each type of AST node is represented as a class, as shown in Figure 2-2.

Figure 2-2. AST nodes as classes.


When we examine the nodes of the tree for this grammar, we see that there may be common properties between different nodes that could be abstracted to superclasses. For example, the PlusOperator and the MinusOperator have similar properties in that they both have left and right operands, which could be abstracted to a class called BinaryOperator. Also, the UnaryPlusOp and the UnaryMinusOp are similar in that they both only have one operand, which could be abstracted to a class called UnaryOperator. Finally, NumberExpression and VariableExpression are literals, and so could be abstracted to a class called Literal. These classes are illustrated in Figure 2-3.

Figure 2-3. AST classes with superclasses.


The tree-structure nature of the AST is supported using the Composite pattern.[11] The intent of the Composite pattern is to "compose objects into tree structures to represent part-whole interactions." The idea is to provide a uniform interface to the objects within such a tree structure, be it a leaf or a composite object. Composite is centered around an abstract class that represents both primitives (in the EES case, literals) and their containers (in the EES case, operators, which "contain" one or two expressions). From the pattern, a container object maintains an aggregation relationship[12] with its parts. As shown in Figure 2-4, the abstract class that is used to represent literals and operators is called Expression. Since both UnaryOperator and BinaryOperator are containers of expressions, they maintain aggregation relationships with Expression.

[11] Erich Gamma, Richard Helm, Ralph Johnson, & John Vlissides. Design Patterns: Elements of Object-Oriented Software. Addison-Wesley 1994.

[12] Booch, Rumbaugh, & Jacobson, The Unified Modeling Language.

Figure 2-4. Composite pattern for AST


Now that we have the basic structure in place, let's look at how to fulfill the EES requirements. Several requirements identified in the specification must be realized in the design: expression support; the evaluation, display, and check-syntax tools, and a logging utility that can be included or excluded from the environment.

There may, of course, be many approaches to the design and implementation of such a system. Since we are assuming the AST structure, a designer might first specify basic structural and accessor properties, as illustrated in Figure 2-5.

Figure 2-5. Core expression design.


It is likely that no behavioral models would be produced to capture any of these basic elements. On the other hand, checking expressions may have sufficiently interesting behavior to be designed using an interaction diagram. An interesting property of designing an interaction with a collaboration model such as a sequence diagram is that only elements relating to the collaboration need to be included. From that perspective, the object-oriented model provides a good level of modularization. Here, we assume a good design for the collaboration required to check the syntax of expressions. From a structural perspective, however, the operations and attributes that are relevant for checking expressions must be included in the core expression class model, as illustrated in Figure 2-6.

Figure 2-6. Support for checking added to core expression diagram.


The design of the evaluate and display requirements is similar, and again, we assume a good design for the collaborations required. The impact on the EES class model is illustrated in Figure 2-7.

Figure 2-7. Evaluate and display added to EES structure.


The remaining requirement to be designed is the optional logging of operation execution. Figure 2-8 shows an example collaboration diagram for logging a check() operation. If the logging utility is turned on (modeled as a Boolean attribute loggingOn), each operation invokes Logger.beforeInvoke() prior to performing its action, then invokes Logger.afterInvoke() just before it terminates. The Logger permits applications to turn logging on and off with its turnLoggingOn()and turnLoggingOff() methods. This permits logging to be optional, as required.

Figure 2-8. Collaboration diagram for logging: example: check().


The impact of the logging requirement on the structure diagram of the EES is illustrated on Figure 2-9. Logging is modeled as a separate, singleton class, Logger. The Singleton design pattern[13] ensures a class has only one instance, as is appropriate for a class performing a logging function that will always behave the same way regardless of what operation is being logged.

[13] Gamma, Helm, Johnson, & Vlissides, Design Patterns.

Figure 2-9. UML class diagram for EES.


Requirements Scattered and Tangled in the EES Design

Earlier in this chapter, we discussed the differing units of interest in the way requirements and objects are described. Requirement units are feature, function, and so on; object, operation, and so on, are the units of interest in object-oriented development. We asserted that while object-oriented designs align well with object-oriented code because of matching constructs, they do not align well with requirements units. This boils down to an issue of modularization. The structural differences in the units of interest between the EES requirements specification and the object-oriented design are central to the difficulties associated with mapping the modularization between the two. The transition between the two essentially results in discarding the encapsulation of requirements' units of interest in favor of units of interest mandated by the design and coding paradigms. The natural outcome is a scattering and tangling effect across the object-oriented design.

Scattering occurs when the design of a single requirement is necessarily scattered across multiple classes and operations in the object-oriented design. The EES requirements of expression evaluation, checking, and display, which are described as modularized concerns in the requirements specification, are not modularized in the design. In fact, these requirements are manifest across the AST classeseach class contains a method that implements these capabilities for its own instances.

Tangling occurs when a single class or operation in the object-oriented design contains design details of multiple requirements. If we look at almost any single class in the EES design, we see design elements from different requirements. Perhaps even more devastating is the tangling effect on one operation in particular: logging. The logging capability is realized as a first-class unit of interest in both the requirements and the design. Nonetheless, the protocol for logging requires cooperation from each method in each AST class to appropriately invoke Logger.beforeInvoke() and Logger.afterInvoke(). This is tanglingsatisfying a given requirement necessitates interleaving design details that address the requirement with details that address other requirements.

Scattering and tangling imply insufficient modularization and are therefore negative from a number of perspectives. First, the impact of change to a single requirement, which may be well localized at the requirements level, can nonetheless be extremely high. This is because that change necessitates multiple changes across a class hierarchy. Second, there is a serious impediment to software comprehension and reuse because it is impossible to deal with the design details relating to one requirement without constantly encountering and having to worry about intertwined details relating to other requirements. Finally, there are significant difficulties with traceability, which is the ability to determine readily how a piece of one software artefact (e.g., requirement, design, code) affects others. Traceability makes it possible to look at a change to a requirement and find those parts of the design and code that are affected by the change. Without matching modularization between the software artefacts, traceability is obscured.

Interestingly, even with a system as small as the EES example, we see a significant level of scattering and tangling in the design. We might look at this particular design and think that it is not so bad, as it would not take long to figure out what is going on. However, extrapolate these problems to a system of any realistic size, and the difficulties are compounded.

We do not claim that recognition of the value of good modularity is newdevelopers seek new means to achieve better modularity all the time. For example, design patterns are one of the most important advances toward good modularity in the last decade. A major goal of design patterns is to allow changes to be made to a system in an additive rather than an invasive manner. This is a very important goal, the key to which is (as with many things!) modularity. In the next section, we look at how we might go about the task of evolving the EES. In order to assess the object-oriented way from a "best practice" perspective, we examine how the use of design patterns improves the basic EES of this section and assess how noninvasive the design patterns really are.



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