Когда класс выполняет сложную и длительную задачу, я обычно реорганизую его поэтапно в зависимости от ситуации, как показано ниже.
Версия 0
public class ComplicatedTaskDoer{
public void doComplicatedTask(){
// lots of complicated code
}
}
Версия 1:
Разбейте его на несколько более мелких подзадач
public class ComplicatedTaskDoer{
public void doComplicatedTask(){
init();
doSubStepA();
doB();
doC();
wrapUp();
}
}
Версия 2:
Если это достаточно сложно, передайте подзадачи на аутсорсинг вспомогательным классам. На самом деле я не использую код для интерфейсов в этом случае.
public class ComplicatedTaskDoer{
public void doComplicatedTask(){
init();
subsetpADoerClass.doA();
classB.doB();
classC.doC();
wrapUp();
}
}
Версия 3:
Если я вижу, что мне нужно добавить больше компонентов в будущем, и если есть допустимый шаблон с точки зрения объектов ввода и вывода, я делаю следующее.
public class ComplicatedTaskController{
//injected
List<SomethingHelperComponent> components;
public void doComplicatedTask(){
init();
for(SomethingHelperComponent component : components){
component.process(commonInput);
}
wrapUp();
}
}
Мне больше интересна версия 3. В итоге я делал это довольно много раз.
Q1) Есть ли какой-нибудь похожий и, вероятно, более эффективный шаблон? Я ищу не «цепочку обязанностей», поскольку я предпочитаю, чтобы эти компоненты были независимыми (открытыми для обсуждения). Это больше похоже на настраиваемый вариант шаблона метода шаблона.
Q2) Я всегда называл основной класс «SomethingController», а вспомогательные классы - «SomethingHelper» или «SomethingComponent». Недавно я понял, что «контролер» вводит в заблуждение, а «помощник» не информативен.
Было бы действительно полезно получить некоторые идеи о том, как правильно назвать эти классы. Как вы их назвали?
Q3) Считаете ли вы, что рефакторинг был разумным?
Q4) Субъективно. Можно ли оставить некоторые шаги во вспомогательных методах и передать некоторые шаги вспомогательным классам? Обычно я воздерживаюсь от модульного тестирования непубличных методов.
Q5) Считаете ли вы, что вспомогательные классы, т. е. без интерфейсов, являются запахом кода? Могу ли я даже объявить их внутренними классами?