我有一个困扰我很长时间的问题。
我有一个数学库,实现为DLL。 该库实现了许多类型的数学函数。 数学函数基于其功能在不同的类中实现。例如,所有实现多项式方程的函数都在CPolynom下,所有实现微分方程的函数都在CDifferential下。
DLL必须公开接口。 现在我的问题是:
我可以在一个头文件中实现,一个接口类包含所有实用类的所有“子”接口方法=>一方面,我只向外界展示一个带有一个类的头文件,另一方面这个类可能很大,包括不相关的接口方法(即有人想要CPolynom功能,他/她将不得不包括巨大的头文件并构造庞大的接口类)
我可以在不同的头文件中为每个类实现接口类。 =>一方面,我根据功能将类拆分为不同的文件。如果有人想要特定功能,他/她将只需要包含相关文件。 另一方面,我最终会向外界介绍许多头文件。
在软件设计学科中,哪种方法更专业,更正确?
谢谢你, 大卫
答案 0 :(得分:1)
我通常每个类实现一个标头。如果你发现自己总是需要一个霰弹枪头,因为你需要“A列中的一个和B列中的两个”,这通常意味着某种设计代码气味。例如,您有一个责任分散在几个类中,而不是集中在一个类中。
答案 1 :(得分:0)
好吧,你总是可以去选项2并创建一个标题,其中包含所有其他标题,这样,如果有人不关心,他将只包括1个大标题,否则,他将能够只包括他需要的东西。
就个人而言,我没有看到一个大标题出现任何问题,当我尝试使用小标题作为用户时,我总是遇到类似“我只需要标题X中的1个函数,标题Y中的2个,...”的问题。 ..“毕竟,我最终在每个* .cpp文件中有15个包含到一个库,这很烦人(所以我实际上自己创建了一个大标题:))。
答案 2 :(得分:0)
我认为你应该为每个类实现接口并将它们放在一个头文件中。无需在预编译头文件中生成大量库头文件。
答案 3 :(得分:0)
一个标题(或少数,如果有很多接口,你可以逻辑地对它们进行分组),但是单独的类也是一个选项。不要像你在选项1中那样用一堆方法创建一个庞大的类。
答案 4 :(得分:0)
头文件的大小仅与编译所需的时间有关。未使用的声明不会影响性能,并且您的代码大小已经通过运送DLL中的所有函数而不是静态链接所需的函数而受到影响。
您是否考虑在库中放置COM接口?用户可以简单地输入单独的.h文件:
#import "mathFunctions.dll" named_guids
自动声明的智能指针然后使函数可用,无需进一步的手动声明甚至清理。您可以在IDL中定义文档,当客户端使用您的代码时,IDL将显示在IDE的工具提示中。您的代码也可以在VB3-6和wscript以及.Net的所有Microsoft语言中重复使用。
double myFunc(double x)
{
double a=1, b=2, c=3, y=0;
MathLib::PolynomPtr polynom(CLSID_CPolynom, 0, CLSCTX_INPROC_SERVER);
y = polynom->someFunction(a, b, c, x); // use it somehow
return y;
}
在进程中使用,COM只为每个函数的执行添加了大约16个周期的开销。因为它是一个智能指针,所以你不必清理它。我没有将它包含在上面,但与外部任何东西一样,你应该添加基本的try / catch功能包装器:
catch (_com_error &e) { printf("COM error: %08x %s\n", e.Error(), e.Description()) };
答案 5 :(得分:0)
选项2看起来对每个人都很自然和专业。
这是大多数库完成的方式。
但是,在同一个标题中对小相关类进行分组(但仍然有几个标题用于整个API)听起来非常合理。
我看到选项1的最大缺点是: - 大型课程中的所有内容都可能难以处理:当开发人员忙于使用CPolynom时,在CDifferential和其他课程之间丢失声明会很痛苦。 - 使用命名空间比更大的“母亲”类更适合聚合类。
简而言之,我会选择选项2,所有类都在库命名空间下。