Theatrical players refactoring Kata
Kata based on the work from Emily Bache.
Objectives
Learn how to refactor “legacy” code
Practice OOP Design Patterns
Practice FP concepts
How to
Clone this repository : https://github.com/ythirion/Theatrical-Players-Refactoring-Kata
Exercise
Add an HTML output with the same information
Facilitation
What do you think about this code ?
import java.text.NumberFormat;
import java.util.Locale;
import java.util.Map;
public class StatementPrinter {
public String print(Invoice invoice, Map<String, Play> plays) {
var totalAmount = 0;
var volumeCredits = 0;
var result = String.format("Statement for %s\n", invoice.customer);
NumberFormat frmt = NumberFormat.getCurrencyInstance(Locale.US);
for (var perf : invoice.performances) {
var play = plays.get(perf.playID);
var thisAmount = 0;
switch (play.type) {
case "tragedy":
thisAmount = 40000;
if (perf.audience > 30) {
thisAmount += 1000 * (perf.audience - 30);
}
break;
case "comedy":
thisAmount = 30000;
if (perf.audience > 20) {
thisAmount += 10000 + 500 * (perf.audience - 20);
}
thisAmount += 300 * perf.audience;
break;
default:
throw new Error("unknown type: ${play.type}");
}
// add volume credits
volumeCredits += Math.max(perf.audience - 30, 0);
// add extra credit for every ten comedy attendees
if ("comedy".equals(play.type)) volumeCredits += Math.floor(perf.audience / 5);
// print line for this order
result += String.format(" %s: %s (%s seats)\n", play.name, frmt.format(thisAmount / 100), perf.audience);
totalAmount += thisAmount;
}
result += String.format("Amount owed is %s\n", frmt.format(totalAmount / 100));
result += String.format("You earned %s credits\n", volumeCredits);
return result;
}
}Will it be easy to do the exercise ?
Why ?

Identify code smells


Does it break any S.O.L.I.D principles ?

How to start ?
Which kind of tests can we do ?
The code already exists and works :
Easiest way to add a regression test is to find some test data, exercise the code, and approve the result
Approval tests : generate output / create your golden master

We store this golden master in a file :
Approval tests : create a test
To do so we can use the library "approvaltests".
The verify is an approvaltests method that will compare the result returned by the print method and our Golden master.
Have we missed something ?
We should ask ourselves if we have covered every piece of code with our test.
To do so we have a tool : code coverage.

The Code Coverage (from IntelliJ here) shows us that the default case is not covered at the moment.

So let's add a new test :
Are we confident enough in our tests ?
To check this we can check the quality of our tests by using a concept called mutation testing.
Improve your test quality with Mutation testing
You can use tools like pitest (for Java) or stryker (for C#, Javascript, Scala).
Now we are confident enough, let's do the exercise.
2 ways of refactoring

To go further
Base artcile from Emily Bache : https://www.praqma.com/stories/refactoring-kata/
Approval Tests : https://approvaltests.com/
Strategy pattern : https://refactoring.guru/design-patterns/strategy
Facilitator slide deck :
Last updated
Was this helpful?