Minesweeper Kata Object Calisthenics with PMD Check
Requirements (copied from CodingDojo.org)
Have you ever played Minesweeper? It's a cute little game which comes within a certain Operating System whose name we can't really remember. Well, the goal of the game is to find all the mines within an MxN field. To help you, the game shows a number in a square which tells you how many mines there are adjacent to that square. For instance, take the following 4x4 field with 2 mines (which are represented by an * character):
*... .... .*.. ....
The same field including the hint numbers described above would look like this:
*100 2210 1*10 1110
You should write a program that takes arbitrary mine fields as input. Each safe square is represented by an "." character (without the quotes) and each mine square is represented by an "*" character (also without the quotes). Your program should output the full minefield with all hint values calculated.
There are sample mine fields and expected outputs in the
- Only One Level Of Indentation Per Method.
- Don't Use The
- Wrap All Primitives And Strings.
- One Dot/Arrow (dereference) Per Line.
- Don't Abbreviate (long names).
- Keep All Entities Small. (50 lines of code per class)
- Not More Than Two Instance Variables.
- First Class Collections.
- No Getters/Setters/Properties.
Checking Code for Compliance
The Code Cop Custom PMD Rules contain PMD rules to check code for compliance with Object Calisthenics.
This project is set up to check the code using the Maven PMD Plugin on each
To check the setup run
mvnw test on the sample code. It will show two violations:
[INFO] PMD Failure: SampleClass.java:2 Rule:TooManyFields Priority:3 Too many fields. [INFO] PMD Failure: SampleClass:9 Rule:NoElseKeyword Priority:3 No else keyword.
You can also check the rules on their own with
By using the Maven Shell the time to run the check can be reduced by 50%.
Limitations of Checking Code
Obviously code analysis cannot find everything.
For example the
PrimitiveObsession rule (Wrap All Primitives And Strings) allows primitive values in constructors and getters because they are needed to implement Value Objects.
On the other hand these getters are getters, so
NoGetterAndSetter will flag them.
Rule #4 (One Dot Per Line) is checked using PMD's own
LawOfDemeter, which checks for the Law Of Demeter. Now the LoD is not about counting dots per line, it is about used types. So sometimes a single dot in a line will already violate the LoD.
Finally it is very difficult to check for abbreviations, so rule #5 is not enforced.
You can use
// NOPMD comments and
@SuppressWarnings("PMD") annotations to suppress false positives.
I recommend using exact suppressions, e.g.
@SuppressWarnings("PMD.TooManyFields") to skip issues because other issues at the same line will still be found. Use your good judgement. The goal of this exercise is to follow all nine rules, not to suppress them.
See my blog post about Object Calisthenics and how to enforce it for more details.
This work is licensed under a New BSD License, see
license.txt in repository.