Как это сделать без нарушения принципа инкапсуляции OOP?
Вы меняете свою интерпретацию принципа инкапсуляции.
Где-то в нашей системе нам нужно иметь две функции: одна, которая принимает представление в памяти объект и преобразует его в сохраненное представление объекта, а также другую функцию, которая восстанавливает объект из сохраненного представления.
Например, у вас может быть метод для объекта, который возвращает JSON представление memento, а затем конструктор объекта, который принимает представление JSON и использует его для инициализации объекта.
По сути, это приложение шаблона Memento из книги GoF. Или вы можете думать о нем как о сообщении, которое отправляется от объекта к объекту.
Это сообщение не обязательно является копией структуры данных объекта; это может быть выражение этой информации по-другому, это может не делиться всей информацией, и так далее. Но если вы хотите получить информацию обратно в сущность позже, вы должны иметь возможность скопировать ее сейчас.
Другой способ думать об этом, который может помочь: мы не храним «сущности», или отправлять объекты по сети - мы отправляем значения по сети; информация упакована в какую-то хорошо понятную схему, чтобы мы могли распаковать ее позже.
Причины, по которым мы можем утверждать, что это не является нарушением «инкапсуляции», двояки: во-первых, сувенир копия - глубокая копия - информации. Мы не можем изменить состояние существующей сущности, изменив память. Во-вторых, нет никаких обещаний или подразумеваемых гарантий, что память имеет ту же структуру данных, что и сама сущность.
То, что делает , - это предположение, что вы можете реализовать сущность без кода, который зависит от вашей стратегии персистентности, потому что вам нужно каким-то образом получить информацию из хранилища данных.