Рефакторинг огромного класса на множество крошечных классов - PullRequest
1 голос
/ 19 декабря 2010

У меня есть прекрасная возможность переработать старый и "вонючий" код
в гораздо лучше разработанную семью класса.

У меня есть базовый проектный скелет, который разобрался, реализован и протестирован .

Однако я дошел до того, что у меня большой класс «Менеджер»
который управляет тем, чем должен (допустим, какая-то хитрая очередь задач),
но он также отвечает за некоторые другие вещи, которые не были моим первым намерением для этого класса.

Создание набора новых классов

class OperationAPerformer
{
    void PerformA(input){...}
}

class OperationBPerformer
{
    void PerformB(input){...}
}

похоже, что не правильное решение. Сохранение логики для OperationA, OperationB в классе менеджера кажется, раздувает класс Manager без веской причины для дизайна

Есть предложения? Спасибо!

Хорошо, я не могу опубликовать весь свой код здесь но базовый дизайн (или скелет)

InitEventHandler  
SubmitEventHandler  
CancelEventHandler  
SuccessEventHandler  
FailureEventHandler  
ProgressReportedEventHandler  
TimeOutEventHandler

...
Обработчики событий обновляют некоторые параметры и сделать некоторую работу управления, как после восстановления после сбоя, Обновление параметров пользовательского интерфейса и т.п. ..

OperationA и OperationB связаны, но восполняют много кода что маскирует главный скелет класса

Связанные операции
SaveProducts () SaveStepA SaveStepB ...

ValidateResponses ValidatePartA ValidatePartB ...

Создание класса, подобного

class Validator
{
   public bool Validate(Response resp) {...}
   private bool PartA(...){...}
   private bool PartB(...){...}
}

кажется неуместным, потому что класс - это только набор связанных методов ... достаточно ли обоснования для создания класса?

Ответы [ 2 ]

4 голосов
/ 19 декабря 2010

Размер сам по себе не является желательным; это просто «запах», причина для выяснения, стоит ли менять код.

Цель класса - не уменьшить размер файла. Предполагается, что это представление принципа организации вашего кода. Если различные операции естественным образом образуют категории (в идеале, потому что они функционально связны, как предполагает Pangea, но в остальном по любой здравой, артикуляционной причине), то разбейте их на отдельные классы менеджеров.

Другие идеи:

Если механизм принятия решений основан на данных, рассмотрим функциональную карту:

interface Performer { public void perform(InputClass input); };
Map<String,  Performer> choices = new HashMap<String,  Performer>();
choices.put("choiceA", 
            new Performer() { public void perform(InputClass input) {
                // ... do action A
            });
choices.put("choiceB", 
            new Performer() { public void perform(InputClass input) {
                // ... do action B
            });

Если решение принимается кодом, тесно связанным с кодом, выполняющим действие, вы можете переосмыслить «выполнить», означая «выполнить, если можете, скажите мне, если не можете»:

interface Performer { public boolean perform(InputClass input); };
List<Performer> pipeline = new LinkedList<Performer>();
pipeline.add(new Performer() { public void perform(InputClass input) {
// ... do action A if you can
});
pipeline.add( new Performer() { public void perform(InputClass input) {
// ... do action B if you can
});

В любом случае, вы можете запечатать конфигурацию внутри менеджера, открыть ее для основной функции, даже извлечь ее из файла конфигурации.

Если ничего из вышеперечисленного не соответствует действительности, и существует просто большое, фиксированное число действий, которые должен выполнять ваш менеджер, рассмотрите возможность укуса пули и просто позволите классу менеджера набухнуть множеством небольших статических функций.

3 голосов
/ 19 декабря 2010

Вы можете разбить классы GOD на несколько классов менеджеров "прецедентов", то есть отдельный класс менеджера для каждого прецедента. Таким образом, каждый класс менеджера является функционально сплоченным, и существует только одна причина для изменения класса менеджера (принцип единой ответственности).

А если вам трудно разбить его на более мелкие классы, это может быть признаком того, что он уже сплочен.

...