3

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

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

+1

Этот [статья] (http://java.dzone.com/articles/serialization-breaks) служит хорошим примером того, как сериализация прерывает инкапсуляцию –

ответ

0

Java-сериализация по умолчанию записывает и считывает поле по полю таким образом, что он раскрывает внутреннюю структуру объекта, которая разрушает инкапсуляцию. Если вы измените внутреннюю структуру класса, вы не сможете правильно восстановить состояние объекта. Хотя с пользовательской сериализацией, если вы изменили класс, вы можете попробовать и изменить readObject, чтобы сохраненные объекты могли быть восстановлены правильно.

1

Отличный вопрос! Сначала давайте определим инкапсуляцию и оттуда. This wikipedia article определяет инкапсуляцию следующим образом:

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

Сериализация, по крайней мере, так, как это делает Java, имеет последствия для обоих этих понятий. Когда вы реализуете интерфейс Serializable на Java, вы, по сути, сообщаете JVM, что все ваши переменные-члены, а не порядок, в которых они объявлены, определяют контракт, по которому объекты могут быть восстановлены из потока байтов. Это работает рекурсивно тогда и только тогда, когда все определения классов переменной члена также реализуют Serializable, и именно здесь вы можете столкнуться с проблемами.

инкапсуляция Проблема

на основе предыдущего определения капсулирования, в частности первого элемента, инкапсуляция мешает вам ничего не зная о том, как объект, который вы имеете дело с фактически работает под капотом, по его переменные-члены. Реализация Serializable «правильно» заставляет вас как разработчика больше узнать об объектах, с которыми вы имеете дело, чем вы, вероятно, заботитесь в функциональном смысле. В этом смысле реализация Serializable прямо противоречит инкапсуляции.

Пользовательская Сериализация

В каждом случае сериализация требует знаний о том, что данные, представляет собой «объект» определенного типа. Интерфейс Java Serializable делает это до крайности, заставляя вас знать состояние transient каждой переменной-члена каждого Object, которое вы надеетесь сериализовать. Вы можете обойти это, определив механизм сериализации, внешний по отношению к типам, которые должны быть сериализованы, но будут компромиссы между проектами - например, вам, вероятно, придется иметь дело с объектами на уровне интерфейса (ов), который они реализуют, вместо прямого взаимодействия с их переменными-членами, и вы можете потерять часть способности восстанавливать точный тип объекта из сериализованного байтового потока.