Read the notes on Reconstruction.

Definition of refactoring

Refactoring is improving the internal structure of the software without changing its observable behavior.

The rhythm of refactoring

Modify the program in small steps. If you make a mistake, it’s easy to spot it.

  • There shouldn’t be a lot of code in a method, we can reorganize it by breaking it down.
  • Good code should clearly express its function, and variable names are the key to clarity.
  • Minimize the number of temporary variables, a large number of parameters passed around, easily lost, poor readability.
  • Extract logical code for functional reuse.

Refactoring, n: An adjustment to the internal structure of software to improve its comprehensibility and reduce its modification costs without changing its observable behavior. Refactoring (verb) : To use a series of refactorings to restructure the software without changing its observable behavior.

Why refactor?

  • Refactoring improves software design
  • Refactoring makes software easier to understand
  • Refactoring helps find bugs
  • Refactoring improves programming speed

When to refactor?

I’m against pull-out time for refactoring in almost any case. In my opinion, refactoring is not something that should be set aside for special time. Refactoring should be done all the time. You shouldn’t refactor for refactor’s sake, you refactor because you want to do something else, and refactor helps you do that.

Three rules

The first time you do something you just do it, the second time you do something similar you get annoyed, the third time you do something similar you should refactor. Three things, three reconstruction.

Why is refactoring useful?

A program that is difficult to modify

  • unreadable
  • Logically repetitive
  • Adding new behavior requires modifying existing code
  • Having complex conditional logic

Good program

  • Easy to read
  • All logic is specified in only one place
  • The new changes do not compromise existing behavior
  • Express conditional logic as simply as possible

Refactoring is the process of taking a currently working program and giving it these nice properties without changing the behavior of the program, allowing us to continue to develop at a high rate, thereby adding value to the program.

When not to refactor?

  • Can’t run stably and rewrite directly without refactoring
  • Projects and deadlines should not be refactored, and while refactoring can increase productivity, you don’t have enough time, which is usually a sign that you should have refactored long ago.

Bad code smell

  • Duplicated Code duplicates Code
  • Long Method An excessively Long function
  • Large Class A Class that is too Large
  • Long Parameter List Indicates the Long Parameter List
  • She has Divergent changes in her life
  • Shotgun Surgery Shotgun Surgery modification
  • Feature Envy Attachment (Strategy Visitor)
  • 4. The Data Clumps
  • And Primitive Obsession
  • Switch Statements (using polymorphic substitution)
  • Parallel Inheritance is Hierarchies
  • Lazy Class redundant Class
  • Speculative Generality refers to the future
  • Temporary Field A confusing Temporary Field
  • Message Chains Are transitively coupled Message Chains
  • Middle Man
  • Inappropriate Intimacy
  • Alternative Classes with Different Interfaces
  • Incomplete Library Class An Incomplete Library Class
  • Data Class Indicates a purely childish Data Class
  • Refused Bequest
  • Comments Too many Comments

When you feel the need to write comments, try refactoring first, trying to make all comments redundant.

Build test architecture

  • Make sure all tests are fully automated and have them check their test results.
  • A suite of tests is a powerful bug scout that can drastically reduce the time it takes to find a bug.
  • Run tests frequently. Take tests into account with each build — run each test at least once a day.
  • Whenever you receive a bug report, write a unit test to expose the bug.
  • Writing imperfect tests and executing them is better than waiting forever for perfect tests.
  • Consider the boundary conditions that could go wrong, and focus your test fire there.
  • When something is supposed to go wrong, don’t forget to check to see if the expected exception is thrown.
  • Don’t stop writing tests just because they can’t catch all bugs, because tests can catch most bugs.

Refactoring list

Refactoring record format

  • The name of the
  • The profile
    • Describe the problem solved
    • Describe what to do
    • Sketch diagrams show examples before and after refactoring
  • motivation
  • practice
  • sample

Basic techniques for refactoring – take small steps and test frequently

There is an inherent relationship between patterns and refactoring. Patterns are where you want to go, refactoring is the way to get there.

Reorganizing function

  • Extract Method Extract function
    • You have a piece of code that can be organized together and isolated. Put this code in a separate function and let the function name explain what the function does.
  • Inline Method Inline function
    • The body of a function should be as legible as its name. Insert the function body at the function call point, then remove the function.
  • Inline Temp is an Inline temporary variable
    • You have a temporary variable that is only assigned once by a simple expression, and it blocks other refactoring methods. Replace all references to the variable with the expression itself that assigned to it.
  • Replace Temp with Query Replaces temporary variables
    • Your program stores the result of an expression in a temporary variable (temp). Extract this expression into a separate function (the Query query). Replace all reference points for this temporary variable with calls to the new function. New functions can be used by other functions.
  • Introducing Explaining Variable Introduce explanation Variable
    • You have a complicated expression. Put the result of this complex expression (or part of it) into a temporary variable whose name explains the purpose of the expression.
  • Split Temporary Variable Splits Temporary variables
    • Your program has a variable assigned more than once. It is neither a loop variable nor a collection temporary variable. For each assignment, create a separate. Corresponding temporary variable.
  • Remove Assignments to Parameters Remove Assignments to Parameters
    • Your code performs an assignment to a parameter. Replace this parameter with a temporary variable.
  • Replace Method with Method Object
    • You have a large function where the use of local variables prevents you from using Extract Method. Put the function in a separate object, so that the local variable becomes the range of values within the object, and then you can break up the large function into smaller functions within the same object.
  • Substitute Algorithm Substitute Algorithm
    • You want to replace one algorithm with a cleaner one. Replace the function body with another algorithm.

Move properties between objects

  • Move Method Move Method
    • There is a function in your program that communicates more with a class outside the class in which it resides: calling the class, or being called by the class. Create a new function with similar behavior in the class most frequently referenced by the function. Make the old function a pure delegate function, or remove the old function entirely.
  • Extract Class Extract Class
    • In your program, a field is used more often by another class outside the class in which it resides. Create a new field in the target class and modify all users of the source field to use the new field.
  • Inline Class internalizes a Class
    • A class does what two classes should do. Create a new class and move the associated ranges and functions from the existing class to the new class.
  • Hide Delegate Hides the Delegate class
    • The client directly invokes the Delegate class of its Server Object. Create all the functions the client needs on the Sever side (a class) to hide the delegate relationship.
  • Remove Middle Man
    • A class has too much simple delegation. Let the client call the delegate class directly.
  • Introduce Foreign Method Introduce external function
    • The server class you are using requires an additional function, but you cannot modify the class. Create a function in the Client class with a Server class entity as its first argument.
  • Introduce Local Extension Introduce Local Extension
    • The server class you are using requires some additional functions, but you cannot modify the class. Create a new class that contains these additional functions. Make this extension a subclass or wrapper class of the Source class.

Reorganizing data

  • Self Encapsulate Field Indicates the self-encapsulation Field
    • You access a field directly, but the direct coupling to the field becomes progressively unwieldy. Create value/set functions for the range, and only these functions access the range.
  • Replace Data Value with Object Replace Data Value with Object
    • You have a data item that requires additional data and behavior. Turn this data item into an object.
  • Change Value to Reference Changes a Value object to a Reference object
    • You have a class that spawns a bunch of equal instances, and you want to replace them with unit objects. Change the value object to a Reference object.
  • Change Reference to Value equals hashCode
    • You have a reference object, which is small, immutable, and difficult to manage. Turn it into a value object.
  • Replace Array with Object Replace Array with Object

    • You have an array, where each element represents something different, and you replace the array with an object. Each element in the array is represented by a range of values.
  • Duplicate Observed Data duplicates “monitored Data”

    • You have some Domain data sitting in GUI controls that the Domain method needs to access. That is, the data is copied to the Domain Object. Create an Observer pattern for synchronizing duplicate data in domain objects and GUI Objects.
  • Change Unidirectional Association to Bidirectional

    • Both classes need to use each other’s features, but there is only one one-way connection between them. Add a reverse pointer and enable the modification function to update both connections simultaneously.
  • Change Bidirectional Association to Unidirectional

    • There is a bidirectional relationship between the two classes, but one class no longer needs the features of the other. Remove unnecessary associations.
  • Replace Magic Number with Symbolic Constant replaces Magic Number with literal Constant

    • You have a literal value with a special meaning. Create a constant, name it according to its meaning, and replace the literal value above with this constant.
  • Encapsulate Field Encapsulate Field

    • Your class has a public range. Declare it private and provide access functions accordingly.
  • Encapsulate Collection Encapsulate collections

    • There is a function that returns a collection. This function returns a read-only image of the cluster and provides a function to add and remove the cluster element in the class.
  • Replace Record with Data Class Replace Record with Data Class

    • You need to deal with record structures in traditional programming environments. Create a dumb Data Object for the Record.
  • Replace Type Code with Class

    • There is a numeric code in the class, but it does not affect the class’s behavior. Replace the numeric type code with a new class.
  • Replace Type Code with Subclasses
    • You have an immutable Type code that affects the behavior of the class. Replace the Type code with a subclass.
  • Replace Type Code with State/Strategy Replace Type Code with State/Strategy
    • You have a Type code that affects the behavior of the class, but you can’t use subclassing. Replace Type code with state Object.
  • Replace Subclass with Fields Replace subclasses with Fields
    • The only difference between your subclasses is in functions that return constant data. Modify these functions to return some (new) value field in the superclass, and then destroy the sublcasses.

Reduced conditional expression

  • Decompose Conditional expression
    • You have a complex conditional statement. Extract separate functions from the if, then, and else paragraphs.
  • Consolidate Conditional Expression Indicates the consolidation condition Expression
    • You have a series of conditional tests, and they all get the same result. Combine these tests into a single condition, and refine the condition into a separate function.
  • Consolidate Duplicate Conditional Fragments to Consolidate Duplicate Conditional Fragments
    • Same code on each branch of the conditional. Move the repeating code out of the conditional.
  • Remove Control Flag Remove Control Flag (break/continue/return)
    • In a series of Boolean expressions, a variable acts as a control marker, which is replaced by a break or return statement.
  • Replace Nested Conditional expressions with Guard Clauses
    • Conditional logic in functions makes it difficult to see the normal execution path. Use guard statements to represent all special cases. For example, if a complex expression is nested with several layers of if-then-else statements, it is converted into multiple if statements to realize its logic. The multiple IF statements are protected statements
  • Replace Conditional with Polymorphism to Replace Conditional expressions
    • You have a conditional that selects different behaviors depending on the type of object. Put each branch of this conditional into an overriding function in a subclass, and then declare the original function as an abstract function.
  • Rule Null Object Introduces Null objects
    • You need to double check that something is null value. Replace null Value with null Object
  • Introduce Assertion
    • A piece of code needs to make certain assumptions about the state of the program. Assertion this assertion clearly.

Simplified function calls

  • Rename Method function
  • Add Parameter Adds parameters
    • A function needs more information from the calling side. Add an object argument to this function that takes in the information the function needs.
  • Remove Parameter Removes a Parameter
  • Separate Query from Modifier Separate Query from Modifier
    • A function either returns the state of a function object or modifies the state of an object. In the future, there will be two different functions, one for query and the other for modification.
  • Parameterize Method makes functions take arguments
    • Several functions do similar work, but contain different values in the function body. Create a single function that takes those different values as arguments.
  • Replace Parameter with Explicit Methods Replace Parameter with Explicit Methods
    • You have a function that takes different actions entirely depending on the parameters. Create a separate function for each possible value of this parameter.
  • Preserve the Whole Object
    • You take values from an object and use them as arguments to a function call. This references (passes) the entire object.
  • Replace parameters with Methods
    • The object calls a function and passes the result as an argument to another function. The function that accepts this argument can also call the previous function. Let the argument receiver remove the argument and call the previous function directly.
  • Introduce Parameter Object Introduce Parameter Object
    • A certain parameter is always naturally occurring at the same time. Replace these parameters with an object.
  • Remove Setting Method Removes the Setting function
    • A value field in your class should be set when the object is first created and never changed. Remove all setting functions for this range.
  • Hide Method Hides the function
    • There is a function that is never used by any other class. Make this function private.
  • Replace Constructor with Factory Method
    • You want to do more than just build an object, replace construcotr with Factory Method
  • Encapsulate Downcast Encapsulates the downward transformation
    • An object returned by a function that requires a downward transition action by the function caller. Move the downward transition action to the function.
  • Replace Error Code with Exception Replace Error Code with Exception
    • A function returns a specific code that represents an error condition. Use exceptions instead.
  • Replace Exception with Test Replace Exception with Test
    • You throw an exception when faced with a condition that the caller can check in advance. Modify the caller so that it checks before calling the function.

Dealing with generalizations

  • The Pull Up Field is moved Up
    • Both subclasses have the same range. Move this range to superclass.
  • The Pull Up Method function moves Up
    • Some functions produce exactly the same effect in each subclass. Move this function to superclass.
  • Pull Up the Constructor Body
    • You have constructors in each subclass whose ontologies are almost identical. Create a new constructor in the superclass and call it in the subClass constructor.
  • Push Down Method moves Down
    • A function in a superclass is related only to part (but not all) of the subclass. Move this function to the relevant subclasses.
  • Push Down Field moves Down
    • A value field in a superclass is used only by part of the subclass. Field this value to the subclasses that need it.
  • Extract Subclass Extract Subclass
    • Some features in class are used by some entities but not all. Create a new subclass and move those features into the subclass.
  • Extract Superclass Extract Superclass
    • Both classes have similar properties. Create a superclass for these classes. Move the same properties to superclass.
  • Extract Interface Extracts interfaces
    • Several customers use the same subset of the Class interface. Alternatively, the interfaces of two Classes are partially the same. Extract the same subset into a separate interface.
  • Collapse Hierarchy
    • There is not much difference between superclass and subclass. Put them together.
  • Form Template Method shapes the Template function
    • There are subclasses where corresponding functions perform similar actions in the same order, but the actions are actually different. By putting each measure into a separate function and keeping them all with the same signature, the original function becomes the same. Then move the original function up to superclass.
  • Replace Inheritance with Delegation
    • A subclass uses only a portion of the superClass interface, or even data that does not need to be inherited. Create a new value field in the subclass to hold the superclass. Adjust the subclass function to delegate superclass instead. Then remove the inheritance relationship between the two.
  • Replace Delegation with Inheritance
    • You use delegate relationships between your two classes and often write extremely simple request functions for the entire interface. Let invite Class succeed to trustee Class.

Large-scale refactoring

  • Tease Apart Inheritance Tease Apart Inheritance
    • A system of succession has two responsibilities. Establish two inheritance systems and delegate relationships so that one can call the other.
  • Convert Procedural Design to Objects
    • You have some code in your hand, written in a traditional procedural style. Turn data records into objects, separate the behavior, and move the behavior into related objects.
  • Separate Domain from Presentation Separate Domain from Presentation/Presentation
    • Some GUI classes include Domain Login (domain logic). Separate domain logInc (domain logic) and create separate domain classes for them.
  • Extract Hierarchy
    • You have a class that does too much work, and one part of the work is done with a lot of conditionals. Establish an inheritance system that represents a special case with a subclass.