Design patterns 将算法封装到类中
我想知道将一个算法封装到一个类中有多(不)常见?更具体地说,与其拥有多个相互转发公共参数的独立函数,不如:Design patterns 将算法封装到类中,design-patterns,coding-style,class-design,Design Patterns,Coding Style,Class Design,我想知道将一个算法封装到一个类中有多(不)常见?更具体地说,与其拥有多个相互转发公共参数的独立函数,不如: void f(int common1, int param1, int *out1); void g(int common1, int common2, int param1, int *out2) { f(common1, param1, ..); } 要将公共参数封装到类中并在构造函数中完成所有工作,请执行以下操作: struct Algo { int common1;
void f(int common1, int param1, int *out1);
void g(int common1, int common2, int param1, int *out2)
{
f(common1, param1, ..);
}
要将公共参数封装到类中并在构造函数中完成所有工作,请执行以下操作:
struct Algo
{
int common1;
int common2;
Algo(int common1, int common2, int param)
{ // do most of the work }
void f(int param1, int *out1);
void g(int param1, int *out2);
};
似乎不必通过函数参数转发公共参数和中间结果是非常实际的。。但我还没有看到这种“模式”被广泛使用。。可能的缺点是什么?如果您需要使用构造函数参数调用这两个方法,那么我会这样做
如果您永远不需要使用相同的参数调用这两个方法,那么我就不需要了。有一种设计模式可以解决这个问题;它被称为“战略设计模式”-你可以找到一些关于它的好信息
“策略”的好处在于,它允许您定义一系列算法,然后互换使用它们,而无需修改使用这些算法的客户端。我通常创建一个函子或封装我的算法 我通常使用以下模板
class MyFunctor {
public:
MyFunctor( /* List of Parameters */ );
bool execute();
private:
/* Local storage for parameters and intermediary data structures */
}
然后我用我的函子这样:
bool success = MyFunctor( /*Parameter*/ ).execute();
这是一个不错的策略。事实上,如果您的语言(使用C++)能够定义某种类型的抽象超类,该类定义了底层功能的不透明接口,那么您可以在运行时交换不同的算法(例如,考虑排序算法)。如果您选择的语言有反射,您甚至可以拥有无限可扩展的代码,允许加载和使用在编写所述算法的使用者时可能不存在的算法。这还允许您松散地耦合其他函数类和算法类,这有助于重构,并在处理大型项目时保持理智 当然,无论何时开始构建一个复杂的类结构,都需要构建和维护额外的体系结构(因此也需要代码)。然而,在我看来,从长远来看,好处大于这个小小的不便 最后一个建议:不要在构造器中工作。构造函数只能用于将类内部结构初始化为合理的默认值。是的,这可能包括调用其他方法来完成初始化,但初始化不是操作。这两者应该是分开的,即使需要在代码中再调用一次才能运行您正在寻找的特定算法。也许更好的方法(除非我遗漏了什么)是在类中重新封装算法,并通过方法调用执行。您可以通过构造函数将所有参数传递给公共属性,也可以创建一个结构,将传递给包含算法的类的所有参数重新封装。但通常在构造函数中执行这样的操作不是一个好主意。首先也是最重要的,因为它不是直观的
public class MyFooConfigurator
{
public MyFooConfigurator(string Param1, int, Param2) //Etc...
{
//Set all the internal properties here
//Another option would also be to expose public properties that the user could
//set from outside, or you could create a struct that ecapsulates all the
//parameters.
_Param1 = Param1; //etc...
}
Public ConfigureFoo()
{
If(!FooIsConfigured)
return;
Else
//Process algorithm here.
}
}
您的问题是否可以更笼统地表述为“当软件的主要思想只是运行一个算法时,我们如何使用面向对象的设计?” 在这种情况下,我认为你提供的设计是一个很好的第一步,但这些东西往往是问题相关的 我认为一个好的总体设计就像你的设计一样
class InputData {};
class OutputData {};
class TheAlgorithm
{
private:
//functions and common data
public:
TheAlgorithm(InputData);
//other functions
Run();
ReturnOutputData();
};
然后,让它与main()或GUI进行任意交互 我希望使用操作符()执行函数对象