A Rule-Based Approach to Framework Evolution
Mariela Cortés, Computer Science Department PUC-Rio.
Rua Marquês de São Vicente, 225 – 22453-900, Rio
de Janeiro, RJ, Brazil.
Marcus Fontoura, Computer Science Department. IBM Almaden Research
Center, 650 Harry Road, 8CC/B1, San Jose, CA, 95120, USA.
Carlos Lucena, Computer Science Department PUC-Rio. Rua Marquês
de São Vicente, 225 – 22453-900, Rio de Janeiro, RJ, Brazil.
|
 |
ARTICLE

PDF Version |
Abstract
Framework development is very expensive, not only because of the intrinsic
difficulty related to capturing the domain knowledge, but also because
of the lack of appropriate methods and techniques to support the evolution
of the framework architecture. In this context, we introduce the concept
of extension rules. Extension rules allow the addition of new features
into the framework design, making sure the consistency with the applications
previously instantiated. We propose the use of extension rules in
combination with the refactoring approach to support framework evolution.
In addition, we propose a methodology to prove the correctness of
evolution processes. The approach is illustrated through Avestruz,
a framework for web searching.
1 INTRODUCTION
A framework is an extensible semi-finished piece of software that
represents a generic solution to a set of applications in a specific
domain. A framework is composed of a kernel subsystem, which is common
to all the applications that may be generated within the framework,
and variation points, which represent areas of variability
within a framework that can be adapted or extended to provide application
specific
behavior [Codenie97]. They are the means by which frameworks provide
the flexibility to build many different applications within a domain.
Therefore, the framework behavior is strongly bound to the behavior
of the applications that may be instantiated from it.
A framework constitutes an ever-evolving representation of our knowledge
of the domain in terms of variations and commonalties. A very important
point is that the framework design should not start by trying to model
its variability and flexibility at once. Instead, a fixed application
should be designed from the framework domain and generalize it only
when the fixed case is understood [Schmid99]. In this context, the
most complex problem regarding framework evolution is the impact of
the changes in the framework design on the rest of the system, and
possible incompatibility with previously defined applications. This
situation represents the principal difference to be considered between
framework evolution and stand-alone application evolution: specialized
rules are needed to support the framework evolution in consistence
with instance applications.
Given the well-known complexity and iterative nature of object-oriented
framework development, the basic philosophy described in [Batory89,
Coad92] may be summarized by:
Framework development is Framework evolution
Framework evolution = Framework refactoring + Framework extension
Refactoring of source code [Opdyke92, Fowler99]
is a well-known approach suggested for the development and evolution
of frameworks by restructuring
a program in the way that it allows other changes to be made more easily.
In early development stages, framework evolution consists in the definition
of a white box structure [Roberts97]. Later, immutable code can be
encapsulated and parameterized by turning the framework into a black-box
one. In specific situations, refactorings can be useful to implement
extensions into the framework design, creating variation points [Fayad99].
The mechanics consists in turning the original behavior (kernel) of
the framework in an alternative behavior that is encapsulated into
a prefabricated class of the framework design. However, refactorings
are not sufficient to deal with this development process. In this paper
we introduce the concept of extension rules to carry out the framework
extension process. On the basis of this concept, we show how the extension
rules can be combined with the refactoring technique to support framework
evolution, and thus, framework development.
Extension rules [Fontoura99, Cortés02, Cortés04] are
based on metapatterns [Pree95], i.e., the basic principles of object-oriented
software construction that describe how to construct frameworks independent
of a specific domain. So-called template and hook methods represent
the metapatterns required to design frameworks. A template method provides
the skeleton of a behavior and a hook method is called by the template
method and can be tailored to provide different behaviors. The different
ways of realizing flexibility (the different types of variation points)
are classified and linked to a metapattern. Metapatterns address the
implementation of flexibility and abstract coupling required in frameworks
at a small scale. Several design patterns are based on metapatterns
[Tokuda01]. The motivation for using metapatterns [Pree95] is to provide
a means to categorize and describe design patterns on a meta-level,
and to support framework construction.
Metapatterns are applied in order to obtain abstract coupling in
a design. They (1) provide the ability to treat several objects (chain
or tree) or a single object uniformly (the Recursive pattern) and (2)
introduce a lower (more abstract) coupling between classes (the Separation
pattern) and methods (the Unification pattern). Thus, the extension
step is carried out more efficiently through extension rules since
a larger number of situations can be modeled, including those shaped
through refactorings. These rules can modify the variation points structure
to support the incorporation of alternative behaviors into the framework
design.
Complicated changes to a program can require both refactorings and
extensions. The combination of refactoring and extension rules to evolve
framework designs in a controlled way is the key point of this work.
These technologies are very useful in developing efficient and flexible
application frameworks and they fit well into the iterative framework
development process. Both refactoring and extension rules preserve
the observable behavior of the original design1. The remainder of this
paper is organized as follows: Section 2 describes the semantics of
refactorings and extension rules. Section 3 presents the methodology
proposed for the formal verification of the evolution processes (refactoring
and extension rules). Section 4 illustrates how refactorings and extension
rules can be applied in practice, using the Avestruz framework as an
example. In Section 5 we comment on some related works. Finally, Section
6 presents our conclusions and future research directions.
2 EVOLUTION PROCESS
In [Butler01], framework development is considered equivalent to the
evolution process involving the execution of two tasks: restructure
and extension. In this work we propose the use of the refactoring technique
[Opdyke92, Fowler99] and extension rules [Fontoura99, Cortés02,
Cortés04], respectively, to support the execution of these tasks.
We consider both techniques as evolution processes which are used to
restructure the code and to add new abstractions.
These evolution processes may be used to avoid the architectural
drift problem [Codenie97] by changing the variation point structure
of the
system. This phenomenon occurs when the framework does not support
the required customization and the application developers need to
violate its structure. As a consequence, the application tends to
drift away
from the framework architecture. When the design modeled by the application
is not a valid instance of a framework, evolution processes may be
applied to add flexibility into the framework design, therefore,
promoting its reutilization but preserving the original behavior,
in the computational
sense. The framework flexibility is based on the variation point
structure that can be accessed by the users (application developers).
Evolution
processes can be considered behavior-extending transformations, since
the cardinality of the application set is increased after its application.
2.1. Refactoring
The refactoring activity involves the redesign of a program unit
to take advantage of good practices in design, such as design
patterns, to improve it. Refactoring is a technique that also plays
a major
role
in Extreme Programming [Roock00] and can occur at various times
throughout the development process. In this section, several refactorings
that
support programming and evolution activities are illustrated.
The transformation represented in Figure 1 represents the Push
Up Method refactoring that moves a common behavior to the abstract
superclass
[Fowler99] to avoid the duplicated code problem. In this example,
since
the same method M() belongs to the classes A and B, a new superclass
is created and the redundant method is moved.

Figure 1. Application of the refactoring Push Up Method
In the resultant class hierarchy the common behavior is concentrated
in the superclass. Meanwhile, specific and additional behavior is
added to the subclasses, avoiding code redundancy. Based on the new
structure, new variant behavior can easily be modeled by the addition
of a variation points to the superclass.
A large part of Fowler’s refactorings [Fowler99] describes methods
to package code properly. The key refactoring in this category is
Extract Method (Figure 2), which takes a code fragment and turns it
into its own method. Subsequently, a call to the new method is used
to replace the removed fragment.

Figure 2. Extract Method refactoring
Extract Method changes the system structure through the incorporation of
the Unification metapattern [Pree95] into the design, where the old
method M1() is transformed into a template method, that invokes the new
(hook)
method M2(). As it will be shown later, this refactoring is used in
the mechanics of several extension rules.
A natural relation between patterns and refactorings is presented
in the design patterns catalogue by Gamma et al. [Gamma95]: “Patterns...
supplies targets for your refactorings”. In other words, refactorings
allows designers to focus on basic patterns when they are developing software
projects. Patterns can be added through refactorings: “… refactorings
turn explicit the design patterns that are subjacent into the code” [Gamma95].
The use of design patterns has costs related to complexity and indirection.
For this reason, design should be as flexible as needed, not as flexible
as possible.
Refactorings have been shown to directly implement certain design
patterns [Tokuda01]. Examples of refactorings with this property
are Replace Type Code with State/Strategy and Form Template
Method [Fowler99]. In the
rest of this section we present some of these refactorings2.
Replace Type Code with State/Strategy implements directly the transformation
that incorporates the State/Strategy pattern into the design (Figure
3). This refactoring substitutes the code type of a generic object
with a state
object, adding one subclass for each type.

Figure 3. Replace Type Code with State/Strategy refactoring In
this way, the variability that before was manipulated through mechanisms
as switch-case features, are manipulated by a class hierarchy in the
target design. Replace Conditional with Polymorphism [Fowler99] describes
a similar
situation. Both of these refactorings are equivalent to the extension
rule Add Unification Pattern (compare Figure 3 with Figure 5 to see the
similarities).
The second example presents the class structure of the Template Method pattern. This pattern defines a skeleton of behavior in a method template,
which can be tailored to provide different behavior through hook methods
in subclasses. This pattern is based on the Unification metapattern
[Pree95].
Form Template Method is a refactoring that incorporates the Template
Method pattern into the design. This refactoring can be applied when
two methods in subclasses (the class hierarchy already exists) execute
similar steps in the same order, yet the steps are different. In the
target design,
the common code is factored in the superclass and the variant behavior
is implemented in the subclasses, preventing the duplication.
2.2. Extension Rules
Extension rules are used to extend the framework behavior, making
it possible to instantiate a greater number of applications. These
rules implement transformations that alter the framework variation
point structure.
The variation point structure introduces variability that is transparent
outside the subsystem, either by inheritance or by composition. Using
extension rules during the evolution process, two situations are possible:
whether
the base class of the variation point subsystem is introduced as a
new class, or whether the responsibility of an existing class is extended
by the responsibility
of the base class. In the first case, we speak of an expanding transformation
since we have expanded the original class structure by a new class.
In the second case, we speak of an extending transformation, since
we have extended
an original class by new responsibilities.
The extension rules are based on framework metapatterns [Pree95],
which implement variation points as a combination of template and
hook methods [Pree91, Gamma95, Pree95]. A template method3 provides
the skeleton of a
behavior. A hook method is called by the template method and can be
tailored to provide different behaviors. Currently, there are four
extension rules,
which automate the incorporation of the basic framework patterns proposed
by Pree [Pree95]. In the remainder of this section we present each
of them by means of a set of short descriptions including:
- The description of the associated metapatterns.
- The motivation to describe why the rule should be implemented.
- The solution proposed.
- The mechanics of how to carry out the evolution.
The evolution processes are illustrated in terms of UML class diagrams.
We use visual representations for the UML-F tags framework and application [Fontoura01].
Add Hook Rule
Description. This rule is used to incorporate a hook method into
the framework design to implement a new variation point.
Motivation. The framework architecture does not support the
required customization because a method of the kernel subsystem
is not
able to realize the behavior required for the application
developer.
Solution. The instance application needs to change the implementation
of a kernel method. In this way, each application can define
alternative behaviors. Figure 4 illustrates this process. 
Figure 4. Application of Add Hook rule
Mechanics. The mechanics can be resumed in the following steps:
- Create a subclass for each instance application, if it does
not already exist.
- Create subclass methods that override the original methods.
- Make the superclass method abstract.
Add Unification Pattern Rule
Description. This rule is used to incorporate the Unification pattern
into the design. This pattern occurs when both the template and hook
methods belong to the same class.
Motivation. Application developers need to add flexibility to existing
methods. The framework architecture does not support the required customization
because the behavior supplied by the kernel methods is not completely
adequate to the behavior required for the application developer. This
might happen in any of the following situations:
- New insights in the domain. Some application specific concepts
may become general concepts and must be incorporated into the framework;
-
New design insights. Some design issues that were neglected in the
framework’s initial design phase are discovered and need to
be incorporated into the framework kernel.
Solution. Variant steps are implemented as a combination of template-hook
methods. The hook method executes the special behavior required by
the application developer. The method might be created through the
Extract Method refactoring [Fowler99], which replaces a fragment
of code with a call to the newly created method.

Figure 5. Application of Add Unification
Pattern rule Mechanics. The mechanics may be summarized
in the following steps (Figure 5):
- Create the new method using the Extract Method refactoring
[Fowler99].
- For each application, if it does not already exist, create
a new subclass.
- Move the implementation of the new method to each subclass
using the Push Down Method refactoring [Fowler99].
- Make the superclass method abstract.
Add Separation Pattern Rule
Description. This rule is used to incorporate the Separation pattern
into the design. This pattern occurs when the template and hook methods
belong to different classes. The application of this rule transforms
a fragment of code from a method in the core into a hook method.
Motivation. The motivation here is the same as the one in Add Unification
Pattern¸ but in this case the final design is more flexible – since
the template and the hooks belong to different classes, adaptations
can happen during runtime.
Solution. Create a new variation point method in a separate hook
class (Figure 6). This variation point must be extended by composition.
In
the obtained design, an additional class is required to host the
template method upon adding to the variation point subsystem.

Figure 6. Add Separation Pattern rule Mechanics. The evolution process in this case may be summarized in following:
- Create the new method using the Extract Method refactoring
[Fowler99].
- Create a new class using the Extract Class refactoring
[Fowler99].
- Create a subclass for each instance application, if it does
not already exist.
- Make the superclass abstract.
Add Recursive Pattern Rule
Description. This rule is used to incorporate the Recursive pattern into the design. This pattern occurs when an
object of the template
class refers objects in the hook class. In particular,
the template class is
a descendent of the hook class.
Motivation. Sometimes, it may be useful to create object
compositions. These compositions can be treated as
a simple object, which
are useful to modify the object behavior without modifying
the class structure already
existent.
Solution. Create an object composition to handle object
collections in order to selectively add or modify
behavior to instances
(Figure 7).
In the Recursive pattern design based
any number of template classes can be defined as subclasses
of H. These
template
classes can define
additional/modified behavior. Note that any number
and combination of instances of template
classes can be attached to instances of H descendants.
During execution time, the hook class H forwards
the control to either descendant (T or T1). The
trick behind this design
is that T1
can modify
the behavior of methods and forward the call
to the object referred by the reference. Furthermore, instance
variables
and methods can be added.
This means that the modified behavior implemented
in the composite class T1 can be attached to
all descendants
of
H. If the call
is forwarded to
a T object, the behavior is preserved; if the
call is forwarded
to a T1 object, the behavior is extended with
the associated
special behavior.
The obtained design is coincident with the structural
pattern Composite [Gamma95]. Thus, the application
of this rule
is useful for incorporating
the corresponding pattern into the design.

Figure 7. Application of Add Recursive
Pattern rule Mechanics. The application of this rule may
be summarized in following:
- Create the composite class.
- Create the abstract superclass.
- Add an instance variable of the composite class in the hook
class.
2.3 Comparing Refactorings and Extension rules
Refactoring activity can be very useful to support framework restructuring
and extension on the basis of specific design patterns. However,
two points differentiating refactoring processes and extension rules
must
be highlighted:
- There are no refactorings for all design patterns (for example,
no refactoring addresses the incorporation of design patterns that
are
based on recursive subsystems). This incompleteness in the refactoring
catalogue [Fowler99] can be solved through the use of extension
rules, which are based on metapatterns. Metapatterns model all the
possible
combinations of template and hooks methods, including the recursive
composition. Consequently, more situations can be described.
- Some refactorings are helpful in the transition of whitebox
frameworks into blackbox frameworks. This process does not change
the framework
behavior since it simply implements restructuring and moving
of code already existing in the framework. In this way, the variant
behavior
that already exists inside the framework becomes explicit in
the design by the use of refactorings. Differently, extension rules
always
incorporate
new variation points into the system.
Design patterns are specific instances of metapatterns, which are
the simplest construction principles. Since extension rules implement
the introduction of metapatterns into the design, design patterns
may be introduced using the same mechanics. Figure 8 describes
some patterns
that may be introduced using refactorings and extension rules.
Each pattern is associated to the correspondent higher level metapattern.

Figure 8. Metapatterns, patterns, extension rules and
refactorings
All referred patterns can be introduced through the extension rules, including
those that can be generated using specific refactorings. Moreover,
the applicability of extension rules is extended to a larger set of different
situations than refactorings. For example, to support the introduction
of patterns based on recursive structures.
3 FORMAL VERIFICATION
Ideally, the behavior preservation of refactorings should be proven
formally [Tokuda01]. In practice and in previous research, this
generally has not been done. Instead of formal proofs, the
approach originally proposed
by Barnejee and Kim for database schema evolution has been adopted
[Banerjee87]. In [Opdyke92] a set of seven invariants to preserve
behavior for refactorings
was proposed, but no proof that these invariants preserved program
behavior was presented.
In this paper we propose a formal methodology to verify the
correctness of the evolution processes (refactoring and extension
rules). In
this sense, the system behavior, both before and after the
evolution process, is formally
defined. Based on the se formal descriptions, equivalence relations
are used to check if the two programs may be considered equivalents.
The methodology
uses CCS [Milner89] as the formalism for the description of
the program behavior and model checking techniques [CWB04] to establish
the behavioral
equivalence. The methodology proposes the following steps for
the formal behavior verification:
- Create the state diagrams on the basis of the state of
variables used by the program, before and after the
program transformation. The diagram denotes the sequence of states.
Each state denotes
a particular situation
of the variables manipulated by the program. To facilitate
this
step the statements in the program are labeled.
- Add the transitions that determine the control sequence
throw in the program execution to the diagrams. The
transitions may be classified into two groups:
- Named. These transitions connect different states in
the diagrams. These transitions are denoted with
different symbols in the diagrams.
- Invisibles. These transitions connect equivalents states
(initial and final) in the diagrams. These
transitions are denoted with
the t (tau) symbol.
- Translate the diagrams into a CCS specification
[Milner89].
- The two formal specifications are incorporated
in the CWB (Edinburgh Concurrency Workbench)
model checking tool. CWB [CWB04] is an interactive
system that allows the user participation throw
commands to check properties and to make analyses. The command
eq is used to
check
the behavioral equivalence
between processes. The system returns true
if the behaviors
of the process may be considered equivalents
in the observational sense, and false in
another case.
In following, we apply the proposed methodology
to verify the correctness of a refactoring process.
In this very
simple example we illustrate
the wrong use of the Rename Method refactoring.
The original code with the
labels and the corresponding sequence of states
is presented in Figure 9. 
Figure 9. Original code and state
sequence before the refactoring process The
refactoring Rename Method is applied to rename the
function F2 to F1. Note that a method with the same
name and parameters already exists in the class
Super. Thus, the behavior of the modified code possibly
was modified. The code after the evolution process
is presented in Figure 10.

Figure 10. Transformed code and
state sequence after the refactoring process In
the next step, the transitions in both sequences
are classified as named or invisibles. The resultant
diagrams of transitions are depicted in Figure
11. In this case all transitions are named.

Figure 11. Transition diagrams
before and after the refactoring process
Figure
12 presents the CCS description of the transition
diagrams described in above. This description is
used as input for the CWB model checking tool.
In the CCS formalism each state in the diagram
is modeled using the agent abstraction. Lines 1
through 7 simply bind agent identifiers to process
expressions. These expressions consist in action_name.
agent_name next. Action_name represents a transition
in the diagram, and the agent_name represents the
target state which can be derivate by the transition.
The line 8 tests the two agents identified by
L1 and L11 for observational equivalence, also
known
as weak bisimilarity

Figure 12. CWB session for the
Rename Method refactoring
The
observational equivalence relation between the
descriptions is determined with the eq command.
Finally, the system responds with the result false (line 9) and the session conclude. In this way,
on the basis of the methodology proposed, is possible
determine that the application of the Rename
Method refactoring in this case is not behavior preserving.
4 STUDY CASE: AVESTRUZ FRAMEWORK
The proposed approach is illustrated through
the Avestruz framework, which is an ongoing
project
at the TecComm Laboratory (PUC-Rio) (http://www.teccomm.les.inf.puc-rio.br).
Avestruz is a search engine framework designed
to process and to parse HTML pages. The processing
determines whether particular words are localized
in the text of the pages. In the crawling process,
links are extracted and stored for future searching.
This is done in parallel, using several machines.
The initial architecture of the framework is
the simplest one that allows accomplishing
these requirements.
The core of the system is the ClScanner class.
It is responsible for localizing the URL of
the initial page of the site and transferring the
control to the HTML processor module to parse
the page.
The abstract class ClHTMLDoc defines a variation
point to allow independence between the framework
and the HTML parser used in the custom applications.
Figure 13 shows the class model and the semantics
of the initial framework design.
When the framework finishes parsing a page
it must recover the next page to be visited
using
the set
of links that was extracted in the parsing
process. During crawling, the index structures
are stored
by the ClScanner class according to the order
of appearance in the HTML documents. Later,
during runtime, applications need more flexibility
and
efficiency for recovering the search results.
Then,
we use extension rules to create a new variation
point in the framework that allows the customization
of the strategy for storing the index information.

Figure 13. Searching engine framework
We use Add Separation Pattern to create a new
entity decoupled from ClScanner class, allowing
customizations in runtime. Figure 14 illustrates
the diagram and semantics for the Avestruz modules,
with the changes generated by the evolution transformation.
During this evolution process, the methods of the
ClScanner class are transformed into template methods
and their specific behavior is translated to the
ClList class.

Figure 14. Adding flexibility for
the link processor module
From the custom application point view, the transformation
is behavior-preserving since the new structure
of the ClScanner (abstract class) and ClList (concrete
class from the user application) is suitable as
the original design. On the other hand, the framework
behavior is extended because a new structure of
template and hooks methods was created during the
evolution process. In the current design, overriding
the hook methods in the ClStoreStrategy class can
modify the behavior of the template class ClScanner.
In its initial design, the ClStoreStrategy class
was specialized to use lists. Later, a new strategy
was developed for storing the page links, ClSmartStorage,
which implements a more intelligent strategy that
determines whether a link is relevant for the current
search. Thus, the search is restricted to a specific
site, avoiding searching in pages outside of the
current scope.
Frequently, a web site includes repeated pages
within a collection of related pages. When the
framework was tested for different applications,
in several situations the best strategy was to
ignore the repeated pages. For that, a new abstraction
was required to model a permanent memory of the
visited pages, adding new requirements to the
design. Consequently, we use extension rules to
add this
evolution to the framework. In this case, we
use Add Separation Pattern rule to create
a new class
decoupled from ClScanner, ClPagesKeeper, to retain
the history of the visited pages. The result
for this transformation is shown in Figure 15.
The
semantics of the scan() method in ClScanner class
is modified by the application of the extension
rule because the specific behavior that implements
the memory of visited pages is extracted and
moved to ClRealKeeper class. If no memory is needed,
the situation may be modeled with the new application
class ClDummyKeeper.

Figure 15. Adding a permanent memory
into the design
When the search of relevant pages is finished,
the search results must be reported to the user.
In the initial solution, the results were returned
through a DOS window. To improve the design and
to avoid the mixing of the result reporting with
the parsing code, we create a new entity representing
the channel that carries out the result reporting.
This step of evolution is a behavior-preserving
transformation because it improves the framework
design but does not add semantics and does not
modify the variation point structure. Consequently,
refactorings come into play to support this evolution
step. The most suitable refactoring for this situation
is Extract Class [Fowler99]. In consequence, the
ClScreenSender class is extracted from ClScanner
class to show the results via DOS window. In this
way, the original class is transformed in two classes
with clear responsibilities: ClScanner and ClScreenSender.
Usually, the custom applications require the
return of formatted results that may be received
via e-mail
when the search is finished, or via browser in
processing time. Variations in the channel implementation
may be required by framework instances. Then,
extension rules can be used to turn the channel
into a variation
point. This can be done by the application of
Add Unification Pattern to create the abstract
class
ClSender (Figure 16).

Figure 16. Defining a channel for
the result reporting
Now, the new framework design allows the customization
of several variation points, however, the answer
processor is still insufficient in some situations.
In particular, the ClScanner class is defined to
accept only a ClSender object. It implies that
the report of the searching results is realized
through only one channel. However, in several situations
reporting through more than one channel may be
useful, e.g., mail and browser simultaneously.
To reach this flexibility, new semantics must be
added into the design. Therefore, extension processes
are used to describe this step of evolution. The
more suitable rule is Add Recursive Pattern, because
it allows creation of a group of channels used
by the custom application to the result reporting,
which are represented by the ClGroupSender class.
Figure 17 represents the final design of the framework
after the evolution process.

Figure 17. Evolution to report
results throws several channels
5 RELATED WORKS
Currently, there are very few framework design
methods that deal with framework evolution. A
pattern-based description of some accepted approaches
underlying framework design can be found in [Roberts97].
Some interesting aspects regarding framework
design such as framework integration, version
control and over-featuring can be found in [Codenie97].
The Refactoring Browser [Roberts97] is a tool
to help maintenance of frameworks written in
Smalltalk.
It currently does not support extension rules,
but it has an open architecture and the introduction
of the extension rules and new refactoring seems
to be straightforward. The design pattern tool
proposed in [Florijin97] also uses refactorings
to achieve framework restructuring.
Roberts and Johnson propose the development of
concrete applications before actually developing
the framework itself [Roberts97]. They claim that
framework abstractions can be derived from concrete
applications. The extension-based development process
may be used to systematize this approach. An approach
that integrates framework and XP is presented in
[Roock00].
A model for framework development based on viewpoints
is proposed in [Fontoura00]. This method was used
as our first approach to framework design, and
the current version has been refined through the
development of several case studies.
In [Schmid99] it was developed an approach to
framework design that considers framework design
as a generalization
problem. Initially, it is fixed a class structure,
which models a specific application from the framework
domain and transforms it by a sequence of generalizing
transformations, each one introducing a variation
point into the class structure. Before the generalization,
the class structure usually contains an aspect
as a frozen spot in the form of a specialized class
or responsibility as a part of a class; in some
cases, an aspect is missing before the transformation.
After the transformation, the class structure contains
a variation point subsystem that represents this
aspect. A generalization transformation [Schmid96]
introduces the variability and flexibility of a
variation point into the class structure. Extension
rules can be used to support these generalization
transformations.
In relation to the formal aspect, a theory for
the formalization of the semantics of framework,
based on the set of application-instance that can
be generated, is presented in [Fontoura99]. This
semantics is defined using sets theory and meaning
functions. However, this theory does not permit
the establishment of property semantics in relation
the behavior. In [Opdyke92], the processes of refactoring
are verified in accordance with a set of program
properties, derivatives of the database area, added
to a property that refers to equivalence semantics
between operations. This latter property is not
formally verified.
6 CONCLUSIONS
In this paper we define a set of rules to support
the flexibilization of the variation point structure
based on the metapattern approach [Pree95]. In
addition, we show how extension rules can be combined
with the well-known refactoring technique [Fowler99]
to support framework maintenance and evolution.
The applicability of the extension rules and refactorings
is analyzed in different stages of the evolution
process. Both the evolution processes: refactorings
and extension rules, are transformations that can
be used to avoid the architectural drift problem
[Codenie97] by restructuring framework variation
point structure during its evolution. As a consequence,
the set of applications that may be instantiated
based on the framework is enlarged, since new variation
points were defined.
In addition, extension rules can be used in the
context of different methodologies for framework
development [Roberts97, Schmid99] to build white
box frameworks [Johnson88] by generalizing from
the classes in the individual applications. The
rules can be useful for evolving frameworks since
the immutable code can be encapsulated and parameterized
by converting the framework into a black-box one.
The paper also proposes a methodology for the
formal verification of the correctness of the evolution
processes. The methodology is based on the CCS
formalism [Milner89] to specify the behavior of
programs. This formal specification will allow
us to think about process properties using model-checking
techniques, for example, to establish the behavioral
equivalence of programs. This methodology, in conjunction
with structural verification (i.e., syntactic analyses,
metrics, etc.), can be very useful for understanding
the evolution process and their consequences on
the framework design and its instance applications.
The ongoing work consist in the extension of
an already existing tool for software refactoring
also supporting extension rules and the elaboration
of new rules for different kinds of variation points.
Footnotes
1 In computational
sense, this implies that these transformations
always result in legal programs equivalent to the
original program.
2 Note that
when refactorings are applied on frameworks, the
variation point structure may be modified, affecting
the set of custom applications.
3 Template
method must not be confused with the C++ template
construct, which has a completely different meaning.
ACKNOWLEDGMENTS
This work is being supported in part by the National
Research Council of Brazil (CNPq).
REFERENCES
[Batory89] Batory D., Barnett J., Roy J., Twichrll
B., Garza J. “Construction of file management
systems from software components”. Proceedings
of COMPSAC. 1989.
[Banerjee87] Banerjee J., Kim W. “Semantics
and Implementation of Schema Evolution in Object-Oriented
Databases”. Proceedings of the ACM SIGMOD
Conference. 1987.
[Butler01] Butler G., Xu L. “Cascaded Refactoring
for Framework Evolution”. Proceedings
of 2001 Symposium on Software Reusability. ACM Press,
p. 51-57. 2001.
[Coad92] Coad P. “Object-oriented patterns”.
Communications of the ACM, v.35, n.9, p. 152-159.
1992.
[Codenie97] Codenie W., Hondt K., Steyaert P.,
Vercammen A. “From Custom Applications to
Domain-Specific Frameworks”. Communications
of the ACM, 40(10), 71-77. 1997.
[Cortés02] Cortés M., 2002. “Computational
Support for the Evolution of Object Oriented Frameworks”.
Proceedings of the Doctoral Simposium of the
International Conference of Software Engineering. Orlando, Florida.
[Cortés04] Cortés M., Fontoura M,
Lucena C. “Refactoring and Unification Rules
to Assist Framework Evolution”. Upgrade
- The European Journal for the Informatics Professional.
Novatica, vol. v, no. 2, pp. 49-55. March 2004.
[CWB04] CWB Model Checking. Available in: http://www.dcs.ed.ac.uk/home/cwb/.
[Fayad99] Fayad M., Schmidt D., Johnson R. “Application
Frameworks”. Building Application Frameworks.
New York: Wiley. p. 3-28. 1999.
[Florijin97] Florijin G., Meijers M, van Winsen
P. “Tool Support for Object-Oriented Patterns”,
ECOOP’97, LNCS 1241, Springer-Verlag, 472-495.
1997.
[Fontoura99] Fontoura M. A Systematic Approach
to Framework Development. Ph.D. Dissertation, Computer
Science Department, Pontifical Catholic University
of Rio de Janeiro. 1999.
[Fontoura00] Fontoura M., Crespo S., Lucena C.,
Alencar P., Cowan D. “Using Viewpoints to
Derive Object-Oriented Frameworks: a Case Study
in the Web-based Education Domain”. Journal
of Systems and Software, 54(3), 239-257. 2000.
[Fontoura01] Fontoura M., Pree W., Rumpe B. The
UML Profile for Framework Architectures, Addison-Wesley.
2001.
[Fowler99] Fowler M. Refactoring: Improving
the design of existing code. Addison-Wesley. 1999.
[Gamma95] Gamma E., Helm R., Johnson R., Vlissides
J. Design patterns. Elements of Reusable Object-Oriented
Software. Addison-Wesley. 1995.
[Milner89] Milner, R. Communicating and concurrency.
Prentice-Hall, Hemel Hempstead. 1989.
[Opdyke92] Opdyke W. Refactoring Object-Oriented
Frameworks, Ph.D. Dissertation, Computer Science
Department, University of Illinois, Urbana-Champaign.
1992.
[Pree91] Pree W. Object-oriented versus conventional
construction of user interface prototyping tools.
Doctoral thesis, University of Linz.
[Pree95] Pree W. Design Patterns for Object-Oriented
Software Development, Addison-Wesley. 1995.
[Roberts97] Roberts D. and Johnson R. Evolving
Frameworks: “A Pattern Language for Developing
Object-Oriented Frameworks”, Pattern
Languages of Program Design 3, Addison-Wesley, R. Martin,
D. Riehle, and F. Buschmann (eds.), 471-486. 1997.
[Roberts97] Roberts D., Brant J., Johnson R. “A
Refactoring Tool for Smalltalk”. Theory
and Practice of Object Systems, Volume 3, Issue 4.
1997.
[Roock00] Roock S. “eXtreme Frameworking
- How to aim applications at evolving frameworks”.
Proceedings of the XP’2000 Conference. 2000.
[Schmid96]
Schmid H. “Design patterns for
constructing the hot spots of a manufacturing framework”.
Journal of Object-Oriented Programming, v. 9, n.3,
p. 325-37. 1996.
[Schmid99] Schmid H. “Framework design
by systematic generalization”. Building Application
Frameworks. New York: Wiley. pp. 353-378. 1999.
[Tokuda01]
Tokuda L., Batory D. Evolving Object-Oriented
Designs with Refactorings. Automated Software Engineering,
v.8, p. 89-120. 2001.
About the authors

|
|
Mariela Cortés received her
BSc degree from the National University of La Plata (UNLP) Argentina,
MSc degree from the Militar Institute of Engineering (IME), Brazil,
and the PhD degree in Computer Science from the Pontifical Catholic
University of Rio de Janeiro (PUC-Rio), Brazil. Her current research
interests include object-oriented design and multi-agents systems
development. At present, she is adjoint professor and researcher
at the State University of Ceará (UECE). Email: mariela@larces.uece.br.
|

|
|
Marcus Fontoura had led several
framework projects and specializes in Web-based software development
and service-oriented architectures in the realm of IBM's Almaden
Research Center. Before that he has held research positions at
the Computer Systems Group of the University of Waterloo, Canada,
and at Princeton University's Computer Science Department. Email:
marcusfontoura@sbcglobal.net.
|

|
|
Carlos Lucena received the BSc degree
from the Pontifical Catholic University of Rio de Janeiro (PUC-Rio),
Brazil, in 1965, the MMath degree in computer science from the
University of Waterloo, Canada, in 1969, and the PhD degree in
computer science from the University of California at Los Angeles
in 1974. He has been a full professor in the Departamento de Informatica
at PUC-Rio since 1982. His current research interests include software
design and formal methods in software engineering. He is member
of the editorial board of the International Journal on Formal Aspects
of Computing. Email: lucena@inf.puc-rio.br. |
Cite this column as follows: Cortés M., Fontoura M., Lucena
C. “A Rule-Based Approach to Framework Evolution”, in Journal
of Object Technology, vol. 5, no. 1, January-February 2006, pp.83-103, http://www.jot.fm/issues/issue_2006_01/article3
|