Совет, который я бы дал, будет зависеть от того, как вы будете генерировать и использовать полиморфы Parcel.Я имею в виду, что мы не можем видеть, какие критерии используются, чтобы определить, является ли что-то «Экспресс» или «Специальным» и связаны ли эти критерии со свойствами самой посылки или каким-либо внешним фактором.
Сказав это, я думаю, что ваша интуиция хороша в том, чтобы отделить расчет цены от самого объекта Parcel.Как указал kmkemp, посылка не должна выяснять, как рассчитать цену посылки в зависимости от типа посылки.Посылка - это объект типа передачи данных / типа POCO, по крайней мере, как указано в вашем сообщении веса, источника и т. Д.
Однако я не совсем понимаю, почему вы используете эти интерфейсы.Не поймите меня неправильно - интерфейс хорош для развязки и тестируемости, но почему есть интерфейс пакета в дополнение к абстрактному базовому классу с абстрактным методом.Лично, используя только ту информацию, которая у меня есть, я бы сделал это:
public class Parcel
{
int SourceCode { get; set; }
int DestinationCode { get; set; }
int weight { get; set; }
}
public abstract class GeneralCalculator
{
//Statics go here, or you can inject them as instance variables
//and they make sense here, since this is presumably data for price calculation
protected static ReadOnlyDictionary<int, List<int>> _States_neighboureness;
protected static ReadOnlyCollection<City> _Citieslist;
protected static ReadOnlyCollection<Province> _Provinceslist;
//.... etc
public abstract Decimal CalculatePrice(Parcel parcel);
}
public class ExpressCalculator : GeneralCalculator
{
public override decimal CalculatePrice(Parcel parcel)
{
return 0.0M;
}
}
public class SpecialCalculator : GeneralCalculator
{
public override decimal CalculatePrice(Parcel parcel)
{
return 0.0M;
}
}
Но, опять же, я не знаю, как на самом деле обрабатываются посылки.Вам может потребоваться какое-то изменение этой концепции в зависимости от того, как вы генерируете, а затем обрабатываете посылки.Например, если тип участка зависит от значений свойств участка, вы можете определить фабричный метод или класс, который принимает участок и возвращает соответствующий экземпляр калькулятора.
Но, как бы вы ни изменяли его, я бы определенно проголосовал за вашу мысль об отделении определения посылки от схемы расчета ее цены.Хранение данных и обработка данных являются отдельными проблемами.Я бы также не проголосовал за статический класс где-то, содержащий глобальные настройки, но это мой личный вкус - такие вещи слишком легко приобретают сеттер и становятся глобальной переменной в будущем.