#java #eclipse #refactoring
#java #eclipse #рефакторинг
Вопрос:
Я хотел бы знать, возможно ли заменить некоторый код вызовом метода, извлеченного ранее.
Например, у меня есть класс с похожими шаблонами:
public class ExtractMethodDemo {
public void doSequence() {
long n1; n2;
// Compute and print count
n1 = 70;
n2 = compute(n1); // <-- 1st
System.out.printf("Input %4s, output = %s.%n", n1, n2); // <-- occurrence
....
// Compute and print count again
n2 = n2 % 100;
n1 = compute(n2); // <-- Nth
System.out.printf("Input %4s, output = %s.%n", n2, n1); // <-- occurrence
}
}
Я рефакторирую, используя метод, но по какой-то причине некоторые вхождения все еще не реорганизованы (возможно, если Replace additional occurrences...
флажок снят, или если тот же код вставлен позже):
public void doSequence() {
long n1; n2;
// Compute and print count
n1 = 70;
n2 = doAll(n1); // <--- method extracted
// ....
// Compute and print count again
n2 = n2 % 100;
n1 = compute(n2); // <--- oops! this one is
System.out.printf("Input %4s, output = %s.%n", n2, n1); // <--- still old style
}
private long doAll(long n) {
long n2; // (BTW: not the n2 declared in doSequence!)
n2 = compute(n);
System.out.printf("Input %4s, output = %s.%n", n, n2);
return n2;
}
Возможно ли впоследствии реорганизовать последовательности повторного преобразования:
public void doSequence() {
long n1; n2;
// Compute and print count
n1 = 70;
n2 = doAll(n1);
// ....
// Compute and print count again
n2 = n2 % 100;
n1 = doAll(n2); // <--- would be great to apply same refactoring afterwards
}
Комментарии:
1. В качестве последнего средства я мог бы повторно встроить весь код и снова извлечь метод, но это не элегантно…
Ответ №1:
Возможно, немного лучше, чем повторное встраивание кода, было бы извлечь метод во всем теле нового кода с Replace Additional Occurrences
checked, а затем встроить новый метод из исходного вызова. Таким образом, вы меньше рискуете выбрать неправильные строки для извлечения.
Обновление: вот пример:
Вы начинаете с
extractableCode(1);
extractableCode(2);
extractableCode(3);
и извлеките исходный блок, оставив вам
extractedMethod(1);
extractableCode(2);
extractableCode(3);
...
function extractedMethod(int i) {
extractableCode(i);
}
Ваш способ — встроить extractedMethod, затем повторить извлечение с заменой всех вхождений. Я предлагаю вместо этого извлечь изнутри extractedMethod()
:
extractedMethod(1);
secondExtractedMethod(2);
secondExtractedMethod(3);
...
function extractedMethod(int i) {
secondExtractedMethod(i);
}
function secondExtractedMethod(int i) {
extractableCode(i);
}
Затем вставьте ваш исходный вызов в первый извлеченный метод:
secondExtractedMethod(1);
secondExtractedMethod(2);
secondExtractedMethod(3);
...
function secondExtractedMethod(int i) {
extractableCode(i);
}
А затем, вероятно, переименуйте второй извлеченный метод. Это лишь немного отличается от того, что вы предлагали изначально, но может быть немного более надежным.
Комментарии:
1. Спасибо. Простите меня, я не понимаю последовательности действий, в частности, что такое «все тело нового кода). В моем примере … 1. Я выбираю две забытые строки (N-е вхождение) 2. Извлекаю в новый метод (например, doAll2). 3. ?