Chapter 7 Reconn-exion
A Ph.D. Thesis by Andrew Le Gear
[Back to Home Page] [Previous Chapter] [Next Chapter]
Part II
“Component Reconn-exion”:
Reengineering Towards Components
Using Variations on Reconnaissance
and Reflexion
“Live out of your imagination, not your history.”
-Stephen Covey.
In the previous two chapters an in-depth review of Software Reconnaissance and Reflexion Modelling was provided. Extensions on both these techniques are used and combined in this chapter to form a process called “Reconn-exion.” This, allied with an evaluation of this process, are the core contributions of this thesis.
In section 2.5.2 the reusability of components was highlighted as being an important quality attribute. Previously in section 3.3 several types of software reuse internal to a system were defined along with techniques for identifying it. In this section we define a new type of software reuse and a means of identifying it.
Software Reconnaissance (chapter 4), showed how source code responsible for implementing observable behavior of a system could be identified by gathering execution profiles. However, another facet of the functionality view provided by Software Reconnaissance is the set of shared software elements. The set of shared software elements
contains software elements that are neither unique to the functionality in question nor utility code common to all features. Rather the software elements are shared across some features but not all. This is calculated as
SHARED(f ) = IIELEMS(f ) -UELEMS(f ) -CELEMS
The set contains software elements that are indispensably involved except for software elements that are unique to that feature or common software elements. The set of shared software elements gives a snapshot of the software elements being reused by the features of the running system, from the context of feature f. Though, difficult to visualise graphically, figure 7.1 is provided to facilitate your understanding of the SHARED set.
In Norman Wilde’s seminal paper on Software Reconnaissance he remarks on the potential worth of the source code shared across features exhibited by a system, but never investigates it further (Wilde and Scully, 1995). We can extend this view by combining the sets of shared software elements for all features in the feature set. This
gives a reuse view for the entire domain(s) or feature class(es) profiled and is calculated as:
Where n is the number of features in a particular feature set. A this point we no longer think of features and source code elements shared by features. The view produced should be simply considered as another reuse view giving an interesting perspective on the software system. We call this view a feature-based reuse perspective of a software system or the reuse perspective for short. In particular this view should contain software elements that are generic, reused and architecturally core in the system. By reused we mean that the software element is used more than one within the context of the features under examination in the reuse perspective. By generic we mean that the potential exists for the elements to be reused in a wider context (i.e. reusable). Finally, by architecturally core, we are again alluding to the idea that the software elements are some what generic. Such architecturally core source code may be generic boilerplate or framework code. The truth of our conjectures on the contents of the reuse perspective will be examined during the evaluation in this thesis and is one of it’s core contributions.
Our hypothesis is that this shared code, that is reused in implementing more than one feature, is a useful starting point that warrants further investigation when identifying code that is reused, reusable, or forms part of architecturally core components of that system. This set is called the ‘reuse perspective’ and is a core contribution of this thesis.
Figure 7.1: The three sets used to form the shared set.
Another component quality attribute identified in chapter 2 was the replacibility quality attribute. This should equally be addressed in a component recovery process just as the reusability quality attribute was addressed in the previous section. Due to the successes of Reflexion Modelling as a means of partitioning a system into higher level abstractions it is one of the conjectures of this thesis that Reflexion Modelling could also be adapted
to unambiguously encapsulate components of existing systems and aid in the definition of their interfaces, thus supporting the important replacibility quality attribute necessary for a good component. We propose the following guidelines for Reflexion Modelling specifically for the encapsulation of components:
1. The programmer creates a high-level model that contains only two nodes:
•A high-level node representing a first attempt at the component he wishes to encapsulate.
•A second high-level node that represents the remainder of the system (see figure 7.2).
2. The programmer maps the appropriate elements of the software system to the nodes in the high-level model.
3. The user then iterates through the traditional Reflexion Modelling process, allowing the tool to build the reflexion model and the programmer to study the edges between the nodes for expected and unexpected dependencies. Refinements at this stage are limited to only changing the map, not the high-level model. This process iterates until he is satisfied that the component has been encapsulated. This, we suggest, explicitly identifies the interface of the component. This is illustrated by figure 7.2.
4. The programmer then proceeds to divide up the rest of the system into its major constituent parts by first iltering the high-level model and then altering the mappings of the map appropriately. The division of the remainder of the system is usually guided by the programmers domain knowledge of the major services provided by the system. This is shown in figure 7.3.
5. Again, the programmer will continue with several iterations until he is satisfied with the new breakdown of the system.
6. The model will now potentially show the dependencies that the component displays with several parts of the system. We suggest that this identifies the roles the component plays in the system.
Of course, the potential for variation upon these guidelines does exist. Some expected variations include:
•A user of the process may decide to define a sub architecture for the component that he is encapsulating.
•A user may not be able to fully clarify the contents of his component until he has begun to break down the remainder of the system.
•A component with a single interface may be encapsulated. It will, at most, have one role in the system.
Figure 7.2: Encapsulating a component and making its interface explicit.
Figure 7.3: Identifying multiple interfaces on a component using Reflexion Modelling.
Two novel approaches, derived from Software Reconnaissance and Reflexion Modelling and designed to aid in the identification and encapsulation of components in software systems have been defined by the two previous sections. This section brings these together as a new process for component recovery called Reconn-exion. Two motivations drive the decision to combine the reuse perspective and the variation on Reflexion Modelling together as a single, aggregated process for component recovery and they are:
•The reuse perspective, generated through the proposed adaptation of Software Reconnaissance, may be a useful means of narrowing the search for reusable, generic and core components of a system. However, it lacks the means of following through and allowing the user to explicitly encapsulate them. Reflexion-based techniques, however, have a proven track record of being able to clearly identify the boundaries and contents of components in existing systems. Given this observation, both the reuse perspective and the variation on Reflexion Modelling
appear complimentary to one another.
•Likewise, Reflexion Modelling has the potential to make components that are recovered more replaceable. However, the identification of clusters, forming the map in a normal Reflexion model is most often based upon naming conventions in the source code (Kosche and Daniel, 2003; Christl et al., 2005). Existing tools explicitly support this by allowing the user to define regular expressions that encompass groupings of software elements with a specified naming convention (Murphy, 2003). Naming conventions have been shown as an excellent means of aiding comprehension and are pervasive throughout industry (Refl, 2005). However, solely relying upon the naming conventions of a system does create a single point of failure for the reflexion modelling technique, hence the variation on it proposed by this thesis and, indeed, by other authors (Christl et al., 2005; Hassan and Holt, 2004). Any means of reducing the dependence upon naming conventions may be a benefit. The reuse perspective is one potential means of reducing this dependence since it is generated by analysing the behavior of the system. The proposed process, illustrated by figure 7.4 will consist of the following steps:
1. The proposed adaptation of Software Reconnaissance is performed on the subject system automatically producing the reuse perspective as output.
2. Then the participant is presented with the reuse perspective of the subject system. He uses this, combined with the existing naming convention approach, to prompt initial mappings for possible component abstractions in the system.
3. From these component abstractions the participant chooses a component of interest that he wishes to recover.
4. The participant can then create his initial Reflexion model, as prescribed by this thesis’ proposed variation, with the map being prompted by the examination of the reuse perspective.
5. Further iterations in the variation on Reflexion Modelling are undertaken.
Figure 7.4: The Component Reconn-exion process.
The participant is free to refer to the reuse perspective at any stage. This continues until the component is encapsulated.
This integrated process for component recovery is called “Component Reconnexion”
and is another core contribution of this thesis.
Table 7.1: Features identified for the house application.
This section introduces a small example to demonstrate the Reconn-exion process.
A small house application is used as the example application. The application was an undergraduate, third year graphics project, created by the author. Figure 7.5 is a screen shot from the application. The purpose of it is to allow the user to manipulate the drawing of the house on the screen. The user can scale the size of the house, change its colour, rotate it and translate it to a different position. The application is approximately 1000 LOC in size, contained in one file and written in Java.
The first part of Reconn-exion requires that a reuse perspective of the system be generated. This involves:
•Identifying the features of the application.
•Exercising appropriate test cases to exhibit and profile the named features.
•Examining the profiles to calculate the reuse perspective.
Figure 7.5: A screenshot of the house application.
The features that were identified by the author in the house application are listed in table 7.1. Next test cases were designed and executed for each feature and their execution was profiled. In this example only one test case is created for each feature, however, one could potentially execute many test cases for a feature, with small profiling differences. The profiles for each of the test cases exercised the following procedures:
•
Test case 1, exhibits feature 1 (Start and Stop the application) and exercises:
– AssignOne9921966.main
– House_GUI.House_GUI
– House_Transforms1.Bezier_Walls
– House_Transforms1.Draw_House
– House_Transforms1.Line_Clipped_House
– House_Transforms1.Setup
– House_Transforms1.bezier
– House_Transforms1.clipcode
– House_Transforms1.clipline
– House_Transforms1.drawLine_Level1
– House_Transforms1.drawLine_Level2
– House_Transforms1.middle
– House_Transforms1.paint
•
Test case 2, exhibits feature 2 (Rotate house) and exercises:
– AssignOne9921966.main
– House_GUI.House_GUI
– House_Transforms1.Bezier_Walls
– House_Transforms1.Draw_House
– House_Transforms1.Line_Clipped_House
– House_Transforms1.Rotate_House
– House_Transforms1.Setup
– House_Transforms1.Translate_House
– House_Transforms1.bezier
– House_Transforms1.clipcode
– House_Transforms1.clipline
– House_Transforms1.drawLine_Level1
– House_Transforms1.drawLine_Level2
– House_Transforms1.matrix_multiplication
– House_Transforms1.middle
– House_Transforms1.paint
•
Test case 3, exhibits feature 3 (Translate house) and exercises:
– AssignOne9921966.main
– House_GUI.House_GUI
– House_Transforms1.Bezier_Walls
– House_Transforms1.Draw_House
– House_Transforms1.Line_Clipped_House
7.4 A Small Example
– House_Transforms1.Setup
– House_Transforms1.Translate_House
– House_Transforms1.bezier
– House_Transforms1.clipcode
– House_Transforms1.clipline
– House_Transforms1.drawLine_Level1
– House_Transforms1.drawLine_Level2
– House_Transforms1.get_firatX
– House_Transforms1.get_firstY
– House_Transforms1.matrix_multiplication
– House_Transforms1.middle
– House_Transforms1.paint
•
Test case 4, exhibits feature 4 (Scale house) and exercises:
– AssignOne9921966.main
– House_GUI.House_GUI
– House_Transforms1.Bezier_Walls
– House_Transforms1.Draw_House
– House_Transforms1.Line_Clipped_House
– House_Transforms1.Scale_House
– House_Transforms1.Setup
– House_Transforms1.Translate_House
– House_Transforms1.bezier
– House_Transforms1.clipcode
– House_Transforms1.clipline
– House_Transforms1.drawLine_Level1
– House_Transforms1.drawLine_Level2
– House_Transforms1.matrix_multiplication
– House_Transforms1.middle
– House_Transforms1.paint
•
Test case 5, exhibits feature 5 (Change house colour) and exercises:
– AssignOne9921966.main
– House_GUI.House_GUI
– House_Transforms1.Bezier_Walls
– House_Transforms1.Draw_House
– House_Transforms1.Line_Clipped_House
– House_Transforms1.Setup
– House_Transforms1.bezier
– House_Transforms1.change_color
– House_Transforms1.clipcode
– House_Transforms1.clipline
– House_Transforms1.drawLine_Level1
– House_Transforms1.drawLine_Level2
– House_Transforms1.middle
– House_Transforms1.paint
Given the profiles listed the reuse perspective can be calculated from the shared sets, as described in section 7.1. Two elements comprise the resulting reuse perspective for the house application:
House_Transforms1.Translate_House : This method is a generic method that can be used to translate coordinates to different positions. It is directly involved in implementing the translate house feature (no. 3), and indirectly involved in the implementation of the rotate and scale house features, making it a generic component,
core to this application.
House_Transforms1.matrix_multiplication : All the features of the house application that involve graphical transforms (no.’s 2,3,4), are implemented, in part, using matrix multiplication. However, the use of the method is not necessarily confined to use with graphical transforms and could potentially be used to multiply any two matrices. Again this makes the method reusable within the application but also reusable in many graphical or maths based applications.
The size of the reuse perspective is small because the set of common software elements is large. As predicted, the elements of the reuse perspective seem architecturally core, generic and reused. Steps one and two of the Reconn-exion process states that the reuse perspective should be presented to a software engineer, where he can examine and use portions or all of it to help him begin the component recovery process. This example provides an excellent starting point to begin recovering a “transforms” component, that encapsulates generic graphical transformation routines, from the house application. Both elements of the reuse perspective, in this case, will form part of the new component. Given larger applications, with larger reuse perspectives, it may be possible to
notice several potential components within the reuse perspective.
Now that we have chosen the component we wish to encapsulate we must describe the component using our adaptation of Reflexion Modelling. We begin by creating a high level model of the application consisting of a transforms component node and a remainder of system component node. For our initial map we map the elements prompted to us by the reuse perspective to the transforms component node and the remainder of the elements to the rest of system component node. This is illustrated by figures 7.6 and 7.7
Figure 7.6: First house application Reflexion model.
<map>
<entry method="matrix_multiplication" mapTo="Transforms" />
<entry method="Translate" mapTo="Transforms" />
<entry method=".*" mapTo="RestOfSystem" />
</map>
Figure 7.7: First house application Reflexion model map.
However, the map prompted from the reuse perspective is very much a seed set with regard to mappings. From this initial reflexion model, prompted by the reuse perspective, we can now attempt the encapsulation of our component. By examining the edges between the transforms component and the rest of the system, further software elements that should be mapped to the transforms component were identified (see figure 7.6). The second reflexion model produced took further elements into the mapped definition of the transforms component. This is shown in figures 7.8 and 7.9. In this case it is interesting to note the seemingly high degree of two way coupling between the transforms component and the rest of the system. On further investigation it was found
that these dependencies were solely on the java framework and could later be ignored. This is the reason that we were later able to remove this link.
Figure 7.8: Second house application Reflexion model.
The edges entering and leaving the transforms component of the reflexion model in figure 7.9 represent the interface that that component provides to and requires of the rest of the system (an investigation of the edge with the jRMTool will provide a list of the software elements involved in that edge). However, we can gain better insight into the different roles that that component plays in the system by investigating in further detail the transforms component’s interaction with other components of the system. For this reason we now begin to divide up the remainder of the system in an effort to reveal multiple interfaces of our component. We decide that the rest of system component can be divided into “GUI,” a component that handles the display of graphics, and “Main,”
which is the main driver of the application. This resembles a model-view-controller (MVC) architectural style. The resulting reflexion model and map for this iteration are shown in figures 7.10 and 7.11
<map>
<entry class="House_Transforms" mapTo="Transforms"/>
<entry method="House_Transforms" mapTo="Transforms"/>
<entry method="matrix_multiplication" mapTo="Transforms"/>
<entry method="Translate" mapTo="Transforms"/>
<entry method="bezier" mapTo="Transforms"/>
<entry method="Bezier_Walls" mapTo="Transforms"/>
<entry method="change_color" mapTo="Transforms"/>
<entry method="clipCode" mapTo="Transforms"/>
<entry method="clipLine" mapTo="Transforms"/>
<entry method="Draw_House" mapTo="Transforms"/>
<entry method="drawLine_Level1" mapTo="Transforms"/>
<entry method="drawLine_Level2" mapTo="Transforms"/>
<entry method="get_first" mapTo="Transforms"/>
<entry method="Line_Clipped_House" mapTo="Transforms"/>
<entry method="middle" mapTo="Transforms"/>
<entry method="paint" mapTo="Transforms"/>
<entry method="Rotate" mapTo="Transforms"/>
<entry method="Scale" mapTo="Transforms"/>
<entry method="Setup" mapTo="Transforms"/>
<entry method=".*" mapTo="RestOfSystem"/>
<entry class=".*" mapTo="RestOfSystem"/>
</map>
<config>
</config>
</rmt>
Figure 7.9: Second house application reflexion model map.
Figure 7.10: Third house application reflexion model.
The reflexion model reveals two interfaces defined by the edges of the Reflexion model. The contents of these interfaces can be found in appendix G. Given an arbitrary system the user may choose to refine their model further from here, prompting further iterations. In this particular case we are satisfied with the component we have
encapsulated.
<map>
<entry method="House_GUI" mapTo="GUI"/>
<entry class="House_Transforms" mapTo="Transforms"/>
<entry method="House_Transforms" mapTo="Transforms"/>
<entry method="matrix_multiplication" mapTo="Transforms"/>
<entry method="Translate" mapTo="Transforms"/>
<entry method="bezier" mapTo="Transforms"/>
<entry method="Bezier_Walls" mapTo="Transforms"/>
<entry method="change_color" mapTo="Transforms"/>
<entry method="clipCode" mapTo="Transforms"/>
<entry method="clipLine" mapTo="Transforms"/>
<entry method="Draw_House" mapTo="Transforms"/>
<entry method="drawLine_Level1" mapTo="Transforms"/>
<entry method="drawLine_Level2" mapTo="Transforms"/>
<entry method="get_first" mapTo="Transforms"/>
<entry method="Line_Clipped_House" mapTo="Transforms"/>
<entry method="middle" mapTo="Transforms"/>
<entry method="paint" mapTo="Transforms"/>
<entry method="Rotate" mapTo="Transforms"/>
<entry method="Scale" mapTo="Transforms"/>
<entry method="Setup" mapTo="Transforms"/>
<entry method="AssignOne9921966" mapTo="Main"/>
<entry class="AssignOne9921966" mapTo="Main"/>
<entry class="House_GUI" mapTo="GUI"/>
</map>
Figure 7.11: Third house application reflexion model map.
[Back to Home Page] [Previous Chapter] [Next Chapter]
Component Reconn-exion by Andrew Le Gear 2006