我有不同的字符串距离度量实现手头(所有这些都在C#中),例如,Levensthein,NeedlemanWunsch,Jaccard等。这些工作基本相同;以两个字符串作为输入并返回范围[0,1]中的相似度分数。所以,我打算让这些类来实现相同的基本界面,如下所示:什么是以下情况的良好设计模式?
public interface IStringDistanceMetric
{
//Return a similarity between 0 and 1.
double CompareSimilarity(string strA, string strB);
}
我的每一个指标都将实现此方法。但是有些指标可以直接对两个字符串进行操作,没有任何其他输入,并且有一些指标需要一些额外的参数(例如对输入字符串之一的间隙进行惩罚等)。一般来说,我可以在构造函数阶段或计算相似性分数之前给这些参数。
我的问题是,一般来说,为了处理具体距离类之间的这种差异,一个好的设计实践是什么?我的目标是,在决定使用特定类型的度量标准之后,希望使用任何距离度量标准的客户端代码应该忽略任何基础实现细节。最明显的办法是实施类似:
IStringDistanceMetric metric;
if(metricType == Metric.NeedlemanWunsch)
{
metric = new NeedlemanWunsch(parametersNW);
}
else if(metricType == Metric.Levensthein)
{
metric = new Levensthein(parametersL);
}
.
.
.
但是这对我来说不是一个好的解决方案。我有点惊讶地发现自己陷入了这样一个基本的外观设计问题。任何帮助,将不胜感激。
你知道你要预先使用哪个吗?也许一个工厂会更适合在这里。这样客户端只需要一个实例,工厂方法就包含这个“if else”的东西并返回接口。这使得工厂可以访问参数的假设 - 它总是可以为这些参数提供参数。还允许您保留您的策略模式,以便返回接口的实现,这很好。 – 2014-10-27 13:07:14
你试图做这件事的方式没有错,你有两个独立的alghorithms检查这两个字符串。让他们在不同的功能和使用if来选择你应该使用哪一个是正确的方式做到这一点。 – Vajura 2014-10-27 13:08:53
同意@AdamHouldsworth。此外,我建议你的客户端代码将“stringDistanceMetric”_typed_作为接口(而不是实际的类类型),因此可以注入不同的具体类型。 – heltonbiker 2014-10-27 13:11:14