У меня есть разные метрические реализации на расстоянии строк (все они находятся на 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' и возвращает интерфейс. Это делает предположение, что фабрика может получить доступ к параметрам - она всегда может принять аргумент для них. Также позволяет сохранить шаблон стратегии для реализации интерфейса интерфейса, что приятно. –
Нет ничего плохого в том, как вы пытаетесь это сделать, у вас есть 2 отдельных алгоритма для проверки этих двух строк. Наличие их в разных функциях и использование if's, чтобы выбрать, какой из них вы должны использовать, - правильный способ сделать это. – Vajura
Согласовано с @AdamHouldsworth. Кроме того, я бы предположил, что ваш клиентский код имеет интерфейс «stringDistanceMetric» _typed_ в качестве интерфейса (а не как фактический тип класса), поэтому вы можете вводить разные типы конкретных типов. – heltonbiker