Code refactoring

Refactoring (also refactoring or restructuring) referred to in the software development manual or automated structural improvement of source code while preserving the observable program behavior. The readability, understandability, maintainability and extensibility are to be improved, with the aim of reducing the time and energy involved for failure analysis and functional enhancements significantly.

Refactoring is a key component of agile software development. There usually " continuous " refactoring or " uncompromising " Refactoring is spoken. Refactoring is in agile software development like coding or module testing an integral part of the software development process and not limited to certain times or phases.

Term origin

The term was first used in a paper by Ralph Johnson and William Opdyke used 1990 ( " Refactoring: An aid in designing application frameworks and evolving object-oriented systems" In: . Proceedings of the Symposium on Object - Oriented Programming Emphasizing Practical Applications ( SOOPPA ), September 1990). Opdyke received his doctorate in 1992 on the subject.

They developed the idea of ​​a software Refactory that ( just the re-factoring ) should facilitate software programs remodeling.

The incorrect translation refactoring comes from a confusion with a frequently cited analogy, which was not originally connotation: Refactoring is a way to modify a program so that hidden structures disclosed without changing its functionality. This, according to the ( erroneous ) conclusion by analogy, corresponds to the procedure of factorization of polynomials in mathematics.

Method

Refactoring is mainly applied to unsightly places in the code (see Code Smell ). In this case the source code of a computer program is redesigned, with the actual program function is to remain unchanged. The transformation of the source code is usually of the following criteria:

  • Legibility
  • Clarity
  • Intelligibility
  • Extensibility
  • Avoid redundancy
  • Testability

The aspects of the refactorings are closely linked with the resulting benefits. Refactoring has an analogue in mathematics in a procedure that is called algebraic manipulation, in which the goal of forming a better readability, comprehensibility, and, where appropriate, extensibility is also ( system of equations ). For this reason functional languages ​​( Lisp, Haskell, OCaml, Erlang, and so on ) are much better suited to perform a refactoring, since they are based on a mathematical paradigm of programming.

Refactoring is facilitated and supported by:

  • Unit tests that can take as regression tests, that the behavior of the program has not changed under the same conditions and not accidentally errors were introduced by the refactoring,
  • Tools, in particular integrated development environments that offer a support to the implementation of refactorings,
  • Functional programming languages ​​(among other things, because you can check code in functional languages ​​with mathematical methods for correctness )
  • A programming language with a strict type system (eg the programming language OCaml ), which in advance ( at compile-time ) excludes many mistakes, because it ensures that the signature (interface) remains the same, even if the structure ( implementation ) changes. This saves a lot of unit tests in advance ( because it excludes many sources of error ).

Possible refactorings

The following are refactorings employed particularly frequently:

  • Change of a symbol name.
  • Move an icon to another module, such as a method in another class.
  • Division of a module ( eg, package, class, method ) into several smaller modules or merger of smaller modules into a larger one.
  • In the broadest sense, the reformatting of the source code, eg using a beautifier.
  • Under different business processes of representation by means of the Unified Modeling Language UML is using " refactoring " the program code to be changed. Thus, a robust and stable system architecture is created due to non- changes must not be initiated in the code.
  • Applying Higher -order functions in functional programming languages
  • Relocating ( refactor'n ) the common abstract logic of multiple modules in functors. ( Functors are parameterized modules that receive modules as parameters and return modules as a result. )

Benefits

Refactoring aims to improve the maintainability of the design in a way that will make it easier for the programmer to extend the existing functional code or reuse elsewhere. This one is trying to achieve by improving the code, in particular with respect to the following criteria:

  • Readability, so that as many programmers understand what the code actually
  • Modularity and redundancy so that specific solutions can be used by another location and is not implemented multiple
  • So that future changes are coupling and cohesion only local effects
  • Testability (see unit test ), so that it is possible to secure the correct operation of the code for the future by regression tests

In conventional software development cycle is a continuing cycle of specification, design, implementation and testing is provided. After each run, the software product may re- enter again and again in this cycle. With the traditional techniques, which meant, however, that an amendment to the specification or a redesign often had to be completely re-written parts or even the entire program. Refactoring allows developers this cycle to be run permanently on a small scale, and thus to improve its product continuously.

Risks and their management

Refactoring is only working code executed ( its functionality is to be maintained ). However, this also includes the risk of unwanted changes and errors. To avoid this risk (or at least minimize ) one uses different rules that make the process of Refaktorisierens hazardous.

First you should have a number automatically running unit tests. These are applied before the refactoring, and you will only begin when the tests all work. This ensures that the program is running properly. After execution of the refactoring the test suite is executed again. So you can see some errors when refactoring immediately. False but would be the statement that unit tests could make the refactoring sure unit tests only reduce the risks of refactorings.

Furthermore, the principle of small changes apply. If you change only little, so one can hope for a even destroy only little, if any one enters by the refactoring error ( still small causes can have large effects ). Secondly, to make mistakes then also easier to find. Often you can break down complex refactorings that one plans in simple small units. Before and after each step is again examined by the tests the integrity of the system. Through the use of automated refactoring features (as they are made ​​available, for example from Eclipse or Borland Delphi Version 2005 ) can also be effectively exclude sources of error and minimize your own effort.

Finally, there is a catalog of refactoring patterns that can be used similar to the design patterns in order to avoid errors. In this case, in each sample, a series of parameters is defined. As would be first ( extract method, rename class, etc. ) is the target of the pattern and then to a series of work instructions that must be executed for this action. Many of these patterns can be automatically implemented by tools nowadays. They meet as a software developer, only to decide which pattern is what used to improve the source code. It should however be noted that the mechanisms are often still quite error prone. At best, it comes through as errors caused a problem during compilation, but also runtime error can be the result. A comprehensive, automated testing is therefore possible for a refactoring always required.

Example

This Java code before refactoring contains a temporary variable that is used for multiple purposes and has a meaningless name:

Double x = 2 * ( width height- );      System.out.println ( "Size :" x);      x = width * height-;      System.out.println ( "Area :" x); By refactoring a separate variable is declared for each of the uses, each wearing a meaningful name:

Extensive double = 2 * ( width height- );      System.out.println ( "Size :" scope );      double area = width * height-;      System.out.println ( "Area :" area ); By further refactoring the two local variables can be eliminated. However, this is only useful if the two local variables find no further use:

System.out.println ( "Size :" (2 * ( width height- )));      System.out.println (" Area: " ( width * height- ) ); literature

  • Martin Fowler: Refactoring. How to Improve the Design of Existing Code. Addison -Wesley Publishing, ISBN 3-8273-1630-8.
  • Robert C. Martin: Clean Code: Refactoring, Patterns, testing and techniques for clean code. Addison-Wesley, Frechen March 2009, ISBN 978-3-8266-5548-7.
  • William C. Wake: Refactoring Workbook. , ISBN 0-321-10929-5.
  • Ch Bommer, M. Spindler, V. Barr: Software Maintenance - Basics, Management and Maintenance techniques, dpunkt.verlag, Heidelberg 2008, ISBN 3-89864-482-0
  • Joshua Kerievsky: Refactoring to Patterns ( = Programmer's Choice ). 1 edition. Addison -Wesley, November 10, 2006 ( Original title: Refactoring to Patterns ), ISBN 978-3-8273-2503-7 ( http://industriallogic.com/xp/refactoring/catalog.html, accessed on March 14, 2013).

Tools

  • Bicyclerepair Refactoringwerkzeug for Python
675870
de