Example code:
// part of an Adder class
public int addAllSquaresOfOddsUp(int[] numbers) {
int sum = 0;
for (int i = 0; i < numbers.length; i++) {
int number = numbers[i];
if (number % 2 == 1) {
sum += number * number;
}
}
return sum;
}
// ... elsewhere ...
// adder is an instance of the Adder class
int total = adder.addAllSquaresOfOddsUp(theNumbers);
Each of the following tasks asks you to extract some part of the presented code into a method. There are 5 questions to answer each time:
number % 2 == 1
with a method call.number * number
with a method call.sum += number * number;
part with a method call.if (...) { ... }
part with a method call.for
loop with a method call.addAllSquaresOfOddsUp
method with a method call.number
so that we don’t have it any more, can it be done? How would the code change?sum
so that we don’t have it any more.sum
local variable as a parameter instead, how would the code change? Would it still work?addAllSquaresOfOddsUp
method with: Creating a new object of a new class and providing the numbers
array as a constructor argument, then calling an invoke
method to perform the steps in the body of addAllSquaresOfOddsUp
method and returning the result of that invoke
call.addAllSquaresOfOddsUp
method into its call so that it is not getting called any more. How would the last line (adder.addAllSquaresOfOddsUp(theNumbers);
) change? What are some things we will need to watch out for when we do this?Example code:
// Method in a Printer class
public void print(int amount, String currency) {
System.out.println(String.format("%d %s", amount, currency));
}
// ... elsewhere ...
// printer is an instance of the Printer class
printer.print(100, "USD");
This is a good example of the “extract parameter object” refactoring. Thinking about it, the parameters amount
and currency
should always go together, as they in effect represent the amount of money we have. Extracting parameters that should go together is a common way to discover new classes.
Money
class, with fields amount
and currency
and a constructor that takes the same as parameters and assigns them to the corresponding fields. The fields are public (for now).print
method takes a single parameter of type Money
, called money
. In the body of the method, references to amount
and currency
are replaced by money.amount
and money.currency
instead.printer.print
at the end takes as input a call to the Money
constructor, passing the amount and currency in to the constructor instead.amount
and currency
fields of Money
private, and provide getters for them. Adjust the code for the print
method accordingly.print
can instead be Money.usd(100)
.String.format("%d %s", money.getAmount(), money.getCurrency())
. Extract a format
method from this, and adjust the code.format
method so that it is an instance method of the Money
class. Adjust the code to match (it should take no arguments as an instance method to Money
).amount
and currency
getter usages, so that the method format
uses the fields directly.