我现在正在开发一个图像二值化库,在这个库中将实现经典的二值化方法,如Sauvola和Otsu方法。现在我的问题是如何优雅地设计图书馆。就目前而言,我有两个解决方案:
解决方案1:
class Binarization
{
public:
BiinterfacePtr interface_;
enum BinarizationMethods
{
Method1, Method2, Method3, Method4
}
void set(BinarizationMethods method, Image *p_in, Image *p_out, Binarizationpara ¶)
{
if (method == Method1)
{
BiinterfacePtr interfacetemp(new BinarizationMethod1());
interface_ = interfacetemp;
}
if (method == Method2)
{
BiinterfacePtr interfacetemp(new BinarizationMethod2());
interface_ = interfacetemp;
}
....
}
bool run()
{
interface_->run();
}
Image* output()
{
return interface->output();
}
}
如您所见,不同的二值化方法的实现是在Biinterface
类中完成的。当我们使用Binarization
类时,我们可以通过调用set
方法来表示我们想要使用的方法。然而,广告不同的二值化方法可能具有不同的参数设置,Binarizationpara
的结构将变得复杂。
解决方案2
class BinarizationMethod1()
{
public:
perform_binarization(Image *p_in, Image *p_out, BinarizationMethod1Para ¶);
}
class BinarizationMethod2()
{
public:
perform_binarization(Image *p_in, Image *p_out, BinarizationMethod2Para ¶);
}
我的问题是哪一个更好。关于设计图书馆的想法将受到欢迎。谢谢!
答案 0 :(得分:2)
我会选择一个简单的strategy pattern,这看起来像是你的第一个解决方案,只有我会使用构造函数注入。我真的不明白为什么要使用枚举,它是紧密耦合的,而不是维护应用程序的最佳方式。您也可以直接将您想要的方法传递给Binarization模块。如果需要将参数传递给方法,只需使用它们的run方法(当然,如果它们都有相同的方法,否则你可以使用方法构造函数)。此外,这使得新方法的创建和维护变得容易。
例如,您可以这样做:
Binarization binarization(new SauvolaMethod()...);
binarization->run();
免责声明:我不是C ++人
答案 1 :(得分:0)
我知道这是一篇旧文章,但是我会为感兴趣的人更新。 这个问题的答案很容易被误导。如果您打算编写高质量的图像二值化库,但是还没想通,那么在开始之前,还需要计划一些事情。
关于第五点,如果您需要提高速度,我有一个建议:模板和奇怪的重复出现的模板模式。
如果您坚持使用OOD方法,那么我还将按照上面的建议使用策略模式,但还要利用外观来提供更干净的体验。>
祝你好运!我是根据经验说的:https://github.com/brandonmpetty/Doxa