Разложение большой функции-члена - PullRequest
3 голосов
/ 28 сентября 2011

Декомпозиция функции-члена

В классе есть функция-член, которая довольно длинная.Допустим, у нас есть

class Customer {
public:
        void process();

...
};

Метод Процесс по своей природе длинный и состоит из пары различных шагов.Вы бы хотели, чтобы эти шаги были собственными функциями, чтобы избежать использования нескольких уровней абстракции в методе процесса.Я думал об этих различных параметрах (включая альтернативу noop):

Создание автономных функций для шагов за пределы класса.

double step_a(vector<Order> orders, double foo);
void step_b(double bar);

void Customer::proccess()
{
        double foo;
        ...
        double bar = step_a(this->orders, foo);
        ...
        step_b(bar);
};

Проблемы: класс является менее самостоятельным-contained.Автономные функции настолько специфичны для функции процесса, что никогда не будут представлять интереса для любого другого кода, поэтому неестественно оставлять их вне класса.

Создавать приватные методы.

class Customer {
public:
        void process();
private:
        double step_a(double foo);
        void step_b(double bar);
};

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

Оставить Customer :: process как есть

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

Вопрос:

Какой самый чистый способ справиться с этим?

(Возможно, ничего из вышеперечисленного, но кое-что, о чем я не думал.)

Ответы [ 2 ]

1 голос
/ 28 сентября 2011

Я бы указал на книги по рефакторингу - особенно «Рефакторинг Мартина Фаулера» и «Рефакторинг Джошуа Кериевского на паттерны».Эта проблема подробно рассматривается в этих книгах.

Описываемый вами «автономный» вариант часто называют «вспомогательными методами»;в этом нет ничего плохого, за исключением того, что они часто становятся ядром метода, и это приводит к взрыву зависимости.

Частные (статические) методы лучше всего подходят, если код напрямую связан с обязанностямикласс в вопросе.

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

1 голос
/ 28 сентября 2011

Вопрос на самом деле не зависит от языка. Не все языки имеют отдельные функции. В C ++ или C # я бы, вероятно, использовал закрытые функции-члены (если возможно, статические).

В C ++ вы можете использовать автономные функции (возможно, в анонимном пространстве имен), чтобы они не были видны снаружи.

...