├── .gitignore
├── README.md
├── pom.xml
└── src
├── main
└── java
│ └── algorithm
│ ├── F.java
│ ├── FT.java
│ ├── Finder.java
│ └── Thing.java
└── test
└── java
└── test
└── FinderTests.java
/.gitignore:
--------------------------------------------------------------------------------
1 | .classpath
2 | .project
3 | .settings/
4 | bin/
5 | target
6 |
7 | .idea
8 | *.iml
9 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Introduction
2 |
3 | Here is the bad news: the new developer you hired has written some terrible, atrocious code.
4 | No one can understand what it does.
5 |
6 | The good news: at least there are unit tests to prove the code is working.
7 |
8 | You job is to refactor the code and make it readable, while keeping the code in working order (pass all tests).
9 |
10 | # How To Start
11 |
12 | 1. Clone this repository `git clone https://github.com/DoDevJutsu/incomprehensible-finder-refactoring-java.git`
13 | 2. Install all the dependencies using Maven.
14 | 3. Run the tests.
15 | 4. Start refactoring!
16 |
17 | The primary goal is to refactor the code in `Finder.java` - as it stands the code is incomprehensible.
18 |
19 | # Tips
20 |
21 | * Start with simple rename refactors so you can better understand the abstractions you are working with. Rename any class or any variable.
22 | * Move on to extract methods and making the code more modular.
23 | * See if you can also eliminate switch statements and multiple exit points from methods.
24 |
25 | Anything is fair game, create new classes, new methods, and rename tests.
26 | The only restriction is that the existing tests have to keep working.
27 | Lean on the tests and run them after every small change to make sure you are on the right path.
28 |
29 | # How to End
30 |
31 | You can stop when you feel the code is good enough, something you can come back to in 6 months and understand.
32 |
33 | # Helpful resources
34 |
35 | ## Refactoring
36 |
37 | * [Martin Fowler Refactorings catalog](http://refactoring.com/catalog/)
38 | * [Refactoring.guru Code Smells catalog](https://refactoring.guru/smells/smells)
39 | * [Refactoring.guru Refactorings catalog](https://refactoring.guru/catalog)
40 | * [CodelyTV Refactoring videos (Spanish)](http://codely.tv/tag/refactoring/)
41 |
42 | # Credits and other programming languages
43 |
44 | This kata is a Java port of the original Incomprehensible Finder Refactoring Kata created by [K. Scott Allen](https://github.com/OdeToCode) and ported by [Tom Cammann](https://github.com/takac).
45 | You can also find [the kata in C#](https://github.com/DoDevJutsu/incomprehensible-finder-refactoring-c-sharp) and [in Php](https://github.com/CodelyTV/incomprehensible-finder-refactoring-kata).
46 |
47 | We put the original Java version in an independent repository in order to make it more easily available for the [Software Craftsmanship Barcelona Coding Dojo session](http://www.meetup.com/Barcelona-Software-Craftsmanship/events/233107734/).
48 | Come with us and have some fun if you're near Barcelona the next Monday, August 22nd!
49 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | algorithm
6 | refactoring
7 | 0.4
8 | jar
9 |
10 | Refactoring Java
11 |
12 | UTF-8
13 |
14 |
15 |
16 |
17 | junit
18 | junit
19 | 4.8.1
20 | test
21 |
22 |
23 |
24 |
25 |
26 | org.apache.maven.plugins
27 | maven-compiler-plugin
28 |
29 | 1.6
30 | 1.6
31 | true
32 | true
33 | true
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/F.java:
--------------------------------------------------------------------------------
1 | package algorithm;
2 | public class F {
3 | public Thing P1;
4 | public Thing P2;
5 | public long D;
6 | }
7 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/FT.java:
--------------------------------------------------------------------------------
1 | package algorithm;
2 | public enum FT {
3 | One, Two
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/Finder.java:
--------------------------------------------------------------------------------
1 | package algorithm;
2 | import java.util.ArrayList;
3 | import java.util.List;
4 |
5 | public class Finder {
6 | private final List _p;
7 |
8 | public Finder(List p) {
9 | _p = p;
10 | }
11 |
12 | public F Find(FT ft) {
13 | List tr = new ArrayList();
14 |
15 | for (int i = 0; i < _p.size() - 1; i++) {
16 | for (int j = i + 1; j < _p.size(); j++) {
17 | F r = new F();
18 | if (_p.get(i).birthDate.getTime() < _p.get(j).birthDate.getTime()) {
19 | r.P1 = _p.get(i);
20 | r.P2 = _p.get(j);
21 | } else {
22 | r.P1 = _p.get(j);
23 | r.P2 = _p.get(i);
24 | }
25 | r.D = r.P2.birthDate.getTime() - r.P1.birthDate.getTime();
26 | tr.add(r);
27 | }
28 | }
29 |
30 | if (tr.size() < 1) {
31 | return new F();
32 | }
33 |
34 | F answer = tr.get(0);
35 | for (F result : tr) {
36 | switch (ft) {
37 | case One :
38 | if (result.D < answer.D) {
39 | answer = result;
40 | }
41 | break;
42 |
43 | case Two :
44 | if (result.D > answer.D) {
45 | answer = result;
46 | }
47 | break;
48 | }
49 | }
50 |
51 | return answer;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/Thing.java:
--------------------------------------------------------------------------------
1 | package algorithm;
2 |
3 | import java.util.Date;
4 |
5 | public class Thing {
6 | public String name;
7 | public Date birthDate;
8 |
9 | public String getName() {
10 | return name;
11 | }
12 | public void setName(String name) {
13 | this.name = name;
14 | }
15 | public Date getBirthDate() {
16 | return birthDate;
17 | }
18 | public void setBirthDate(Date birthDate) {
19 | this.birthDate = birthDate;
20 | }
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/src/test/java/test/FinderTests.java:
--------------------------------------------------------------------------------
1 | package test;
2 | import static org.junit.Assert.assertEquals;
3 |
4 | import java.util.ArrayList;
5 | import java.util.Date;
6 | import java.util.List;
7 |
8 | import org.junit.Before;
9 | import org.junit.Test;
10 |
11 | import algorithm.F;
12 | import algorithm.FT;
13 | import algorithm.Finder;
14 | import algorithm.Thing;
15 |
16 | public class FinderTests {
17 |
18 | Thing sue = new Thing();
19 | Thing greg = new Thing();
20 | Thing sarah = new Thing();
21 | Thing mike = new Thing();
22 |
23 | @Before
24 | public void setup() {
25 | sue.name = "Sue";
26 | sue.birthDate = new Date(50, 0, 1);
27 | greg.name = "Greg";
28 | greg.birthDate = new Date(52, 5, 1);
29 | sarah.name = "Sarah";
30 | sarah.birthDate = new Date(82, 0, 1);
31 | mike.name = "Mike";
32 | mike.birthDate = new Date(79, 0, 1);
33 | }
34 |
35 | @Test
36 | public void Returns_Empty_Results_When_Given_Empty_List() {
37 | List list = new ArrayList();
38 | Finder finder = new Finder(list);
39 |
40 | F result = finder.Find(FT.One);
41 | assertEquals(null, result.P1);
42 |
43 | assertEquals(null, result.P2);
44 | }
45 |
46 | @Test
47 | public void Returns_Empty_Results_When_Given_One_Person() {
48 | List list = new ArrayList();
49 | list.add(sue);
50 |
51 | Finder finder = new Finder(list);
52 |
53 | F result = finder.Find(FT.One);
54 |
55 | assertEquals(null, result.P1);
56 | assertEquals(null, result.P2);
57 | }
58 |
59 | @Test
60 | public void Returns_Closest_Two_For_Two_People() {
61 | List list = new ArrayList();
62 | list.add(sue);
63 | list.add(greg);
64 | Finder finder = new Finder(list);
65 |
66 | F result = finder.Find(FT.One);
67 |
68 | assertEquals(sue, result.P1);
69 | assertEquals(greg, result.P2);
70 | }
71 |
72 | @Test
73 | public void Returns_Furthest_Two_For_Two_People() {
74 | List list = new ArrayList();
75 | list.add(mike);
76 | list.add(greg);
77 |
78 | Finder finder = new Finder(list);
79 |
80 | F result = finder.Find(FT.Two);
81 |
82 | assertEquals(greg, result.P1);
83 | assertEquals(mike, result.P2);
84 | }
85 |
86 | @Test
87 | public void Returns_Furthest_Two_For_Four_People() {
88 | List list = new ArrayList();
89 | list.add(sue);
90 | list.add(sarah);
91 | list.add(mike);
92 | list.add(greg);
93 | Finder finder = new Finder(list);
94 |
95 | F result = finder.Find(FT.Two);
96 |
97 | assertEquals(sue, result.P1);
98 | assertEquals(sarah, result.P2);
99 | }
100 |
101 | @Test
102 | public void Returns_Closest_Two_For_Four_People() {
103 | List list = new ArrayList();
104 | list.add(sue);
105 | list.add(sarah);
106 | list.add(mike);
107 | list.add(greg);
108 |
109 | Finder finder = new Finder(list);
110 |
111 | F result = finder.Find(FT.One);
112 |
113 | assertEquals(sue, result.P1);
114 | assertEquals(greg, result.P2);
115 | }
116 |
117 | }
118 |
--------------------------------------------------------------------------------