Software Refactoring
A key goal of development AntiPatterns is to describe useful forms of software refactoring. Software refactoring is a form of code modification, used to improve the software structure in support of subsequent extension and long-term maintenance. In most cases, the goal is to transform code without impacting correctness.
Good software structure is essential for system extension and maintenance. Software development is a chaotic activity, therefore the implemented structure of systems tends to stray from the planned structure as determined by architecture, analysis, and design. Software refactoring is an effective approach for improving software structure. The resulting structure does not have to resemble the original planned structure. The structure changes because programmers learn constraints and approaches that alter the context of the coded solutions. When used properly, refactoring is a natural activity in the programming process. For example, the solution for the Spaghetti Code AntiPattern discussed later in this chapter defines a software development process that incorporates refactoring.
Refactoring is strongly recommended prior to performance optimization. Optimizations often involve compromises to program structure. Ideally, optimizations affect only small portions of a program. Prior refactoring helps partition optimized code from the majority of the software.
Formal Refactoring Transformations
Formal refactoring transformations include superclass abstraction, conditional elimination, and aggregate abstraction. These formal refactorings originated in Opdyke’s PhD thesis [Opdyke 92]. They are called formal refactorings because implementations can be proven not to affect program correctness. It’s also possible to automate these transformations. The following refactorings involve changes to object classes, implementations, and relationships.
• Superclass abstraction. This refactoring applies to two or more similar classes. A superclass abstraction creates an abstract class that merges the common implementations of several concrete classes. To perform a superclass abstraction, the program transformation involves: (a) transformation of similar method signatures to common method signatures, (b) creation of an abstract superclass, (c) code modification to merge selected implementations, and (d) migration of common methods to the abstract superclass.
• Conditional elimination. This refactoring applies when the structure and behavior of a class is heavily dependent upon a conditional statement. The steps are: (a) create new subclasses corresponding to each condition, (b) migrate the action code from the conditional to the new subclasses, and (c) redirect class references to refer to the subclass types as appropriate. This last change can affect constructors, type declarations, and invocations of overloaded methods. The modified references should maintain the original logical states from the conditional, as invariant assertions on the new classes.
• Aggregate abstraction. An aggregate abstraction reorganizes class relationships to improve their structure and extensibility. This transformation can take several forms: (a) conversion of inheritance relationships to aggregate relationships, (b) migration of aggregated classes to component relationships, or (c) migration of component relationships to aggregate relationships.
These three, large-grain refactorings are dependent upon dozens of small-grain program transformations [Opdyke 92], which are familiar to virtually all programmers. Examples of small-grain transformations include: (a) renaming classes, methods, and attributes; (b) creating new classes; (c) migrating functionality between classes; (d) converting direct references to indirect pointers, and so forth. For a complete list, consult Opdyke (1992).
Sunday, August 12, 2007
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment