Conditions | 17 |
Total Lines | 58 |
Code Lines | 28 |
Lines | 0 |
Ratio | 0 % |
Tests | 22 |
CRAP Score | 18.0513 |
Changes | 1 | ||
Bugs | 0 | Features | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like fr.arakne.utils.maps.LineOfSight.between(CoordinateCell,CoordinateCell) often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
1 | /* |
||
67 | public boolean between(CoordinateCell<C> source, CoordinateCell<C> target) { |
||
68 | 1 | if (source.x() == target.x() && source.y() == target.y()) { |
|
69 | 1 | return true; |
|
70 | } |
||
71 | |||
72 | 1 | if (source.x() == target.x()) { |
|
73 | 1 | return checkWithSameX(source, target); |
|
74 | } |
||
75 | |||
76 | // Swap source and target to ensure that source.x < target.x |
||
77 | 1 | if (source.x() > target.x()) { |
|
78 | 1 | final CoordinateCell<C> tmp = source; |
|
79 | |||
80 | 1 | source = target; |
|
81 | 1 | target = tmp; |
|
82 | } |
||
83 | |||
84 | 1 | final int yDirection = source.y() > target.y() ? -1 : 1; |
|
85 | 1 | final double ySlope = (double) (target.y() - source.y()) / (double) (target.x() - source.x()); |
|
86 | 1 | final double yAtZero = source.y() - ySlope * source.x(); |
|
87 | |||
88 | 1 | int currentY = source.y(); |
|
89 | |||
90 | // For every X between source and target |
||
91 | 1 | for (int currentX = source.x(); currentX <= target.x(); ++currentX) { |
|
92 | // yMax is the value of Y at the current X |
||
93 | 1 | int yMax = (int) Math.round((currentX + 0.5) * ySlope + yAtZero); |
|
94 | |||
95 | for (;;) { |
||
96 | // target is reached : do not check it's LoS |
||
97 | 1 | if (currentX == target.x() && currentY == target.y()) { |
|
98 | 1 | return true; |
|
99 | } |
||
100 | |||
101 | // Ignore the source LoS |
||
102 | 1 | if (currentX != source.x() || currentY != source.y()) { |
|
103 | 1 | if (cellSightBlocking(currentX, currentY)) { |
|
104 | 1 | return false; |
|
105 | } |
||
106 | } |
||
107 | |||
108 | // Increment Y until yMax is reached |
||
109 | 1 | if (currentY == yMax) { |
|
110 | 1 | break; |
|
111 | } |
||
112 | |||
113 | 1 | currentY += yDirection; |
|
114 | } |
||
115 | } |
||
116 | |||
117 | // Increments Y until target is reached |
||
118 | for (; yDirection > 0 ? currentY < target.y() : currentY > target.y(); currentY += yDirection) { |
||
119 | if (cellSightBlocking(target.x(), currentY)) { |
||
120 | return false; |
||
121 | } |
||
122 | } |
||
123 | |||
124 | return true; |
||
125 | } |
||
161 |