>我正在编写一个函数来执行特定任务。此函数需要一些临时数据来处理任务。问题是如果我在这个函数中做所有事情,那么这个函数的大小会很大。然后我考虑将这个函数分解成许多小函数。但是如果我这样做,我需要将一些临时数据传递给这些小函数。它使代码看起来不是很好。因此,我考虑创建一个具有私有数据的类,包括输入,输出和临时数据,并且这些小函数成为类的方法。下面是代表我的想法的伪代码。
/* big function */
output big_function(input)
{
temporary_data data1;
temporary_data data2;
temporary_data data3;
temporary_data data4;
/* do task here*/
...
return output;
}
/* many small function*/
output function1(input)
{
temporary_data data1;
temporary_data data2;
temporary_data data3;
temporary_data data4;
/*do some thing */
function2(input,data1,data2, data3, data4);
output = function3(input,data1,data2, data3, data4);
return output;
}
/* use class*/
class Task
{
public:
Task(input);
function1();
output get_output();
private:
function2();
function3();
private:
input;
output;
data1;
data2;
data3;
data4;
}
我的问题是:用类来表示任务是一种正确的方式吗?
使用对象的成员变量以避免参数传递通常会导致代码非常脆弱和难以阅读的代码(类似于使用全局变量)。
在我看来,你想要的是:
output function(input);
而不是对象所需的三个(实际上是四个)步骤:
Task t(input);
t.function1();
output o = t.get_output();
// destructor is implicitly called at some point
这样做的另一个问题是,t
上的函数必须按特定顺序调用(@VolAnd在他的评论中提到了这一点)。
为了解决传入和传出大量参数的问题,将结构传入和传出函数(因此在调用它们时很清楚读取的内容和修改的内容):
struct params {
temporary_data data1;
temporary_data data2;
temporary_data data3;
temporary_data data4;
};
如果合适,使用多个结构来传达和强制临时数据中的状态更改(例如,struct unsortedData
和struct sortedData
)。
类的公共接口以及内部结构取决于许多因素:
- 如何使用类(许多实例或单线程,多线程与否等)
- 什么是
temporary_data
(结构、类、集合/数组或只是简单类型) - 临时数据量和存储数据的位置(将使用的内存 - 静态、自动(堆栈)或动态(堆))
- 其他相关事项(如错误处理、输入输出检查等)
对于最简单的实现(一个函数调用调用其他函数的解决方案),我的建议是考虑:
- 使用一个静态方法创建类
output solve_task(input)
而不是三个 -Task(input)
(构造函数)、function1()
(运行解决方案)和output get_output()
(获取结果) - 私有字段和方法也必须是静态的才能从
solve_task
调用 solve_task
可以尽可能简单,例如
output solve_task(input)
{
if(!check_input(input))
{
// reaction on wrong input
throw(badInput);
}
// data preparation
function1(input); // init private fields
function2(input); // find/fill the temporary data
// solution
function3(); // works with internal temporary data
...
functionN(); // works with internal temporary data
// providing result
return prepare_output()
}