Лучшее место для сериализации кода.Внутренний для сериализуемого класса или внешний класс для формата? - PullRequest
4 голосов
/ 11 ноября 2011

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

Стандартная сериализация на болоте не представляет никакой сложности.Просто украсьте класс, о котором идет речь.

Мой вопрос больше относится к классам, которые сериализуются по множеству протоколов или в разные форматы и требуют некоторой мысли / оптимизации процесса, а не просто слепой сериализации декорированных свойств.

Мне часто кажется чище хранить весь код для одного формата в своем классе.Это также позволяет вам добавлять больше форматов, просто добавляя новый класс.например.

class MyClass
{
}

Class JSONWriter
{
    public void Save(MyClass o);
    public MyClass Load();
}

Class BinaryWriter
{
    public void Save(MyClass o);
    public MyClass Load();
}

Class DataBaseSerialiser 
{
    public void Save(MyClass o);
    public MyClass Load();
}

//etc

Однако это часто означает, что MyClass должен предоставить гораздо больше своих внутренних объектов внешнему миру, чтобы другие классы могли эффективно сериализоваться.Это кажется неправильным и идет против инкапсуляции.Есть способы обойти это.например, в C ++ вы можете сделать сериализатора своим другом, или в C # вы можете выставить некоторых членов в качестве явного интерфейса, но он все еще не чувствует себя прекрасно.

Другой вариант, конечно, это знать MyClassкак сериализовать себя в / из различных форматов:

class MyClass
{
    public void LoadFromJSON(Stream stream);
    public void LoadFromBinary(Stream stream);

    public void SaveToJSON(Stream stream);
    public void SaveToBinary(Stream stream);
    //etc
}

Это выглядит более инкапсулированным и правильным, но оно связывает форматирование с объектом.Что если некоторый внешний класс знает, как сериализовать более эффективно из-за некоторого контекста, о котором MyClass не знает?(Может быть, целая куча объектов MyClass ссылаются на один и тот же внутренний объект, поэтому внешний сериализатор может оптимизировать, только сериализовав это один раз).Кроме того, если вам нужен новый формат, вы должны добавить поддержку во всех ваших объектах, а не просто писать новый класс.

Есть мысли?Лично я использовал оба метода в зависимости от конкретных потребностей проекта, но мне просто было интересно, есть ли у кого-нибудь веские причины для или против конкретного метода?

Ответы [ 2 ]

2 голосов
/ 11 ноября 2011

Я полагаю, что это действительно зависит от контекста, в котором будет использоваться сериализация, а также от ограничений систем, использующих ее. Например, из-за ограничений отражения Silverlight некоторые свойства класса должны быть доступны для работы сериализаторов. Еще один, сериализаторы WCF требуют от вас знать возможные типы времени выполнения ad-hoc.

Помимо того, что вы указали, введение логики сериализации в класс нарушает SRP. Зачем классу нужно знать, как «перевести» себя в другой формат?

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

2 голосов
/ 11 ноября 2011

Самый гибкий шаблон - это облегчение объектов и использование отдельных классов для определенных типов сериализации.

Представьте себе ситуацию, если вам потребовалось добавить еще 3 типа сериализации данных. Ваши классы будут быстро раздуты с кодом, который им не нужен. «Объекты не должны знать, как они потребляются»

...