Как бы вы исправили следующий плохой код, который передает слишком много параметров?
void helper1(int p1, int p3, int p5, int p7, int p9, int p10) {
// ...
}
void helper2(int p1, int p2, int p3, int p5, int p6, int p7, int p9, int p10) {
// ...
}
void foo(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8,
int p9, int p10) {
helper1(p1, p3, p5, p7, p9, p10);
helper2(p1, p2, p3, p5, p6, p7, p9, p10);
}
Я вижу два разных подхода:
Подход 1. Поместите все функции в класс
class Foo {
private:
int p1, p2, p3, p4, p5, p6, p7, p8, p9, p10;
void helper1() {}
void helper2() {}
public:
void foo() {
helper1();
helper2();
}
// add constructor
};
Подход 2. Просто передайте параметры как класс
struct FooOptions {
int p1, p2, p3, p4, p5, p6, p7, p8, p9, p10;
};
void helper1(const FooOptions& opt) {
// ...
}
void helper2(const FooOptions& opt) {
// ...
}
void foo(const FooOptions& opt) {
helper1(opt);
helper2(opt);
}
В чем преимущества и недостатки подходов?
Преимущество подхода 1 состоит в том, что - если вы сделаете helper
функции виртуальными - вы можете создавать подклассы и перегружать их, добавляя гибкости. Но в моем случае (помимо приведенного мной мини-примера игрушек) такие помощники часто являются шаблонными, поэтому они все равно не могут быть виртуальными.
Преимущество подхода 2 состоит в том, что вспомогательные функции можно легко вызывать и из других функций.
(Этот вопрос связан, но не обсуждает эти две альтернативы .)