Temporary Field
Description (What)
A field in a class that is given its value and then subsequently used by particular methods and are undefined in the rest of the cases.
How to Locate It (Where)
Look for fields that aren't explicit assigned a value in the constructor or are assigned default or garbage values in the constructor and fields that are used only in one method in the class and are assigned their proper values in that method.
Also look for fields that get their value based on type code/if-else/switch statements where they get their value based on satisfying a condition but remain unassigned in other conditions.
How it Manifests (Why)
Temporary fields might arise from the need of variables for complex algorithms or functions in a class that need them and are required to be defined in the fields of the class.
How to Fix It (Possible Treatments)
In Example 1, we use Extract Class. This treatment moves the fields and the methods that require them into their own class such that in the new class, the field is always assigned a proper value. This way the field is always populated with a correct value on object instantation.
In Example 2, Introduce Null Object is used. This treatment introduces a Null Object to prevent Null-Pointer error.
Other treatments are also possible based on the specific scenario, they can be found here
Examples
Example 1
Before:
Variables a and b are always used but c is used only when Quadratic/Cubic equations need to be solved and d only when Cubic equations need to be solved.
Observed Code Smells:
- Temporary Field (lines 4-5)
After:
Applied Extract Class to extract all the methods into their own Classes 'LinearSolver', 'QuadraticSolver' and 'CubicSolver' and deleted the original 'PolynomialSolver' class
Refactoring Applied:
- Temporary Field
- Extract Class (LinearSolver, QuadraticSolver, CubicSolver)
Observed Code Smells After Refactoring:
- None
Example 2
Before:
The line 50 is checking if a customer is null, considering this case of nullable customer is reasonable
in such a scenario, some object should be created to capture this situation and prevents program crashes
from NullPointer issues.
Observed Code Smells:
- Temporary field (line 40, 47, 54)
After:
Apply Introduce Null Object by creating a new subclass of Customer called NullCustomer,
mostly just an informative temp variable for checking for null.
Refactoring Applied:
- Temporary Field:
- Introduce Null Object (line 22, line 40-48, line 56, line 65, line 74)
Observed Code Smells After Refactoring:
- None
When to Ignore
None
More
- Example 1
- Example 2
- Before
- After
001 class PolynomialSolver {002 private int a;003 private int b;004 private int c;005 private int d;006007 public PolynomialSolver(int a, int b) {008 this.a = a;009 this.b = b;010 }011012 public PolynomialSolver(int a, int b, int c) {013 this.a = a;014 this.b = b;015 this.c = c;016 }017018 public PolynomialSolver(int a, int b, int c, int d) {019 this.a = a;020 this.b = b;021 this.c = c;022 this.d = d;023 }024025 public void solveLinear() {026 if (this.a == 0) {027 if (this.b == 0) {028 System.out.println("Infinite Solutions");029 } else {030 System.out.println("No solution");031 }032 } else {033 System.out.println(-this.b / this.a);034 }035 }036037 public void solveQuadratic() {038 // check if c exists039040 if (this.a == 0) {041 solveLinear();042 }043044 double discriminant = Math.pow(this.b, 2) - 4 * this.a * this.c;045046 if (discriminant > 0) {047 double x1 = (-this.b + Math.sqrt(discriminant) / (2 * this.a));048 double x2 = (-this.b - Math.sqrt(discriminant) / (2 * this.a));049 System.out.println("Solutions: " + x1 + ", " + x2);050 } else if (discriminant == 0) {051 double x = (-this.b) / (2 * this.a);052 System.out.println("One real solution: " + x);053 } else {054 double real = -this.b / (2 * this.a);055 double imaginary = Math.sqrt(Math.abs(discriminant)) / (2 * this.a);056 System.out.println("Complex solution: " + real + ", " + imaginary);057 }058 }059060 public void solveCubic() {061 //check if c, d exists062063 if (this.a == 0) {064 System.out.println("Coefficient 'a' is zero, solving as a quadratic equation:");065 solveQuadratic();066 return;067 }068 double B = this.b / this.a;069 double C = this.c / this.a;070 double D = this.d / this.a;071 double p = C - B * B / 3;072 double q = D - (B * C) / 3 + 2 * (B * B * B) / 27;073 double delta = (q / 2) * (q / 2) + (p / 3) * (p / 3) * (p / 3);074 if (delta >= 0) {075 double u = Math.cbrt(-q / 2 + Math.sqrt(delta));076 double v = Math.cbrt(-q / 2 - Math.sqrt(delta));077 double y1 = u + v;078 System.out.println("One real solution for cubic equation (from Cardano's method): x = " + (y1 - B / 3));079 System.out.println(080 "Note: Finding the other two roots involves complex numbers or more intricate calculations.");081 } else {082 double phi = Math.acos((-q / 2) / Math.sqrt(-((p / 3) * (p / 3) * (p / 3))));083 double y1 = 2 * Math.sqrt(-p / 3) * Math.cos(phi / 3);084 double y2 = 2 * Math.sqrt(-p / 3) * Math.cos((phi + 2 * Math.PI) / 3);085 double y3 = 2 * Math.sqrt(-p / 3) * Math.cos((phi + 4 * Math.PI) / 3);086 System.out.println("Three real solutions for cubic equation (trigonometric method):");087 System.out.println("x1 = " + (y1 - B / 3));088 System.out.println("x2 = " + (y2 - B / 3));089 System.out.println("x3 = " + (y3 - B / 3));090 }091 }092 }093094 public class TFBE1 {095 public static void main(String[] args) {096 PolynomialSolver ps = new PolynomialSolver(10, 12);097 ps.solveLinear();098 PolynomialSolver ps2 = new PolynomialSolver(10, 12, 14);099 ps2.solveQuadratic();100 PolynomialSolver ps3 = new PolynomialSolver(10, 11, 12, 13);101 ps3.solveCubic();102 }103 }104