Должны ли классы сохранять и загружать себя через XML? - PullRequest
1 голос
/ 02 августа 2011

Так что, в основном, я ищу ответ на этот вопрос передового опыта. У меня есть система, которая в основном представляет собой набор правил, некоторые данные и менеджер, чтобы убедиться, что данные соответствуют правилам. Довольно просто Я пытаюсь выяснить лучший способ обработки сохранения и загрузки правил. Для первой попытки у меня есть интерфейс IRule, который наследуется всеми правилами.

interface IRule
{
  /* all rules inherit this */
  string RuleName {get;}
}
interface IRuleTypeA : IRule
{
  /* Type A Rules */
  double[] Data;
}

interface IRuleTypeB : IRule
{
  /* Type B Rules */
  double[,] Data;
}

public static class IRuleExtensions
{
  XElement AsXml(this IRuleTypeA ruleA)
  {
    //format my data my way and return an XElement representation
    return new XElement(...);
  }
  XElement AsXml(this IRuleTypeB ruleB)
  {
    //format my different data in a different way and return an XElement
    return new XElement(...);
  }
  XElement AsXml(this IRule rule)
  {
    object definition = null;
    if(rule is IRuleTypeA)
      definition = (rule as IRuleTypeA).AsXml();
    else if(rule is IRuleTypeB)
      definition = (rule as IRuleTypeB).AsXml();
    return new XElement("RuleDefinition", new XAttribute("name", rule.RuleName),
                         definition);
  }
}

Итак, я помещаю функцию сохранения в сохраняемый класс. Я собирался реализовать подобный механизм загрузки, который будет принимать каждый элемент и создавать правила. Прежде чем сделать это, я хотел посмотреть, есть ли лучшие практики по этому поводу. Стоит ли вместо этого создать отдельную систему, которая будет принимать правило, опрашивать его, затем сохранять его в XML и использовать систему фабричного типа для использования XML для создания объектов обратно?

interface RuleToXmlAdaptor
{
  XElement AsXml(IRule rule);
  IRule FromXml(XElement element);
}
class RuleAToXmlAdaptor : RuleToXmlAdaptor
{
  XElement AsXml(IRule rule) { return AsXml(rule as IRuleTypeA); }
  XElement AsXml(IRuleTypeA rule);
}

Я перебираю эти методы, не зная, когда использовать тот или иной метод, или если есть еще лучшее решение.

Я не хочу использовать сериализацию, потому что тип файла может постоянно меняться, и я могу довольно просто управлять совместимостью таким образом.

Ответы [ 3 ]

6 голосов
/ 02 августа 2011

Я не думаю, что сам класс должен знать что-либо о том, как его можно сериализовать.Это нарушает принцип единоличной ответственности.Подумайте о случае, когда завтра выйдет новый потрясающий формат сериализации, скажем SoupML.Если вы позволите кому-то вне объекта позаботиться о сериализации, тогда будет действительно легко заставить вашу систему работать хорошо с SoupML, и вам даже не придется изменять существующие модели правил.

В идеале только теМодули, которые явно используют XML, должны знать XML, таким образом, ваша система может состоять из блоков, которые не заботятся о формате, а только об интерфейсах.Где-то позже им скажут, какой сериализатор / десериализатор использовать (Inversion of Control).Наличие этого способа также поддерживает принцип открытия-закрытия.Вам не придется открывать вещи для модификации, но они будут открыты для расширения.

0 голосов
/ 02 августа 2011

Я бы так не поступил, потому что это связывает ваши руки, хотя в краткосрочной перспективе это может быть удобнее.Вместо XElement почему бы интерфейсу не выставить Dictionary<string,object>.Тогда у вас могут быть пары ключ-значение (с хорошо известными типами значений, такими как String и Dictionary<string,object>).Таким образом, модульное тестирование будет проще, и вы сможете использовать более эффективный формат, если захотите.

interface RuleSerializer
{
  Dictionary<string,object> AsDictionary(IRule rule);
  IRule FromDictionary(Dictionary<string,object> data);
}
0 голосов
/ 02 августа 2011

Я думаю, вы должны начать искать атрибуты xml, которые можно использовать в вашем классе, и свойства, которые позволяют легко сериализовать объект класса в файл xml и снова десериализовать его при необходимости.

...