У меня есть проблема, которая должна быть решена с помощью шаблона проектирования, который мне неизвестен. Это для преобразований между различными системами координат. Я объясняю вам.
1 / У меня есть перечисление, ссылающееся на набор системы (EPSG):
public enum System
{
NAD27 = 3800,
NAD83 = 3801,
...
WGS84 = 4326
}
Это перечисление позволяет определить систему использования объектом Координата.
public struct Coordinate
{
public System system;
public double X;
public double Y;
public double Z;
}
Может существовать бесконечность систем. Индексы перечисления не обязательно следуют друг за другом и не должны изменяться.
2 / Необходимо, чтобы объекты могли переходить из одной системы в другую. Я применяю преобразования из одной системы в другую. Система A -> Система B. Это преобразование не меняет тип. Он изменяет значения координат (x, y и z), так что точка находится в нужном месте в зависимости от ее системы.
Возможны все комбинации. Однако, в зависимости от начальной системы, расчеты для смены систем не всегда одинаковы.
3 / У меня есть несколько классов stati c, содержащих методы преобразования:
public static class WGS84
{
public static Coordinate ToNAD27 (double X, double Y, double Z)
{
...
}
public static Coordinate ToNAD83 (double X, double Y, double Z)
{
...
}
}
Мы Приходите к проблеме.
4 / Чтобы определить, какое преобразование использовалось, и чтобы избежать множества случаев, когда я впервые использовал переключатель, принимающий в качестве аргумента объект, содержащий исходную систему и прибывающую систему:
public class SystemTransform
{
public System initial;
public System terminal;
}
public struct Coordinate
{
public System system;
public double X;
public double Y;
public double Z;
public Coordinate Transform (SystemTransform s)
{
switch(s)
{
case SystemTransform st when st.Initial == System.WGS84 && st.Terminal == System.NAD27:
return WGS84.ToNAD27(X, Y, Z);
...
case SystemTransform st when st.Initial == System.WGS84 && st.Terminal == System.Z:
throw new NotImplementedException ($ "{s} not implmented");
}
}
}
5 / Будучи непрактичным и эстетичным c, я обратился к словарю:
public static class TransformWithDictionary
{
private static Dictionary <SystemTransform, Func <Coordinate , Coordinate >> ParserMap = new Dictionary <SystemTransform, Func <Coordinate , Coordinate >>
{
{new SystemTransform (System.WGS84, System.NAD27), coord => WGS84.ToNAD27(coord)},
{new SystemTransform (System.WGS84, System.NAD83), coord => WGS84.ToNAD83(coord)},
};
public MyObject GetParserFor (SystemTransform st, Coordinate coord)
{
if (! ParserMap.ContainsKey(st))
throw new NotImplementedException ("Unexpected file type value" + st);
return ParserMap[st](coord);
}
}
Это немного класснее, но это не решает проблему.
В теории я сталкиваюсь с переключателем с возможностью ∞. Достаточно сказать, что невозможно заполнить его вручную и поддерживать в течение долгого времени.
Третья идея заключалась в создании фабрики. Но это никак не помогает мне определить, какую функцию использовать в соответствии с системой происхождения и системой прибытия.
Есть ли у вас идея шаблона проектирования для решения этой проблемы?