Использование шаблона команды в Java для сохранения/загрузки

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

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

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

Соответствующая часть моего кода класса Command:

private GameController controller;
private Tile sourceTile;
private Tile[] route;

public MoveCommand(GameController controller, Tile sourceTile, Tile... route) {
    this.controller = controller;
    this.sourceTile = sourceTile;
    this.route = route;
}

@Override
public void execute() {
    controller.executeMove(sourceTile, route);
}

Я намерен изменить ссылки Tile на ссылки на новый сериализуемый класс с именем TileLocation или что-то в этом роде, который будет содержать целые числа X и Y, чтобы плата могла находить плитки.


person DavidH    schedule 15.03.2012    source источник
comment
обратите внимание, что может быть случайность, если вы всегда используете один и тот же PRNG, а также сохраняете семя. Только сохранение пользовательского ввода и начального числа - очень хороший способ сделать это (как ни странно, я делал это для своей платформенной игры (где-то игра до сих пор хранится)... в 1993 году ;) Несколько крупных игр, таких как Warcraft III, StarCraft 2, и т. д. используют именно эту технику для сохранения игр и повторов. Вот почему повторы такие маленькие, даже если есть несколько игроков с сотнями юнитов, каждый из которых играет в течение одного часа: количество пользовательских вводов, которое может произвести пользователь, ограничено...   -  person TacticalCoder    schedule 16.03.2012
comment
в качестве дополнительного преимущества такой метод также упрощает воспроизведение состояния вашей программы/игры и, следовательно, может помочь отлаживать/отслеживать гораздо легче, чем когда вы не используете такой трюк. Единственным недостатком является то, что вам, вероятно, нужно добавить номер версии к каждому сохранению, потому что как только логика изменится, ваши старые сохранения больше не смогут загружаться...   -  person TacticalCoder    schedule 16.03.2012


Ответы (2)


Нет ничего плохого в том, чтобы хранить ваше игровое состояние и ходы как целые числа. Но я бы не рекомендовал использовать сериализацию Java для длительного хранения. (будет практически невозможно обновить игровые классы и перечитать сохраненные состояния). Используйте какую-либо привязку данных XML или JSON (Jackson, GSON, что угодно) для долгосрочного сохранения.

person Konstantin Pribluda    schedule 15.03.2012
comment
Хорошая информация, мне нужно использовать сериализацию в этом случае по личным причинам, но я знаю и использовал Xstream раньше, что было очень полезно в предыдущем проекте для сериализации объектов в XML и обратно. - person DavidH; 22.03.2012

Я бы также возражал против сериализации и вместо этого выбрал бы JSON или XML. Однако, если вам необходимо выполнить сериализацию, вы можете использовать ключевое слово "transient" для любой переменной-члена, чтобы предотвратить ее включение в сериализацию.

private transient int x = 0;

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

person Matt    schedule 17.03.2012
comment
Я уже знал об использовании временных полей таким образом, но не рассматривал возможность их использования вместе с отражением для создания независимого от класса метода сериализации. Спасибо. - person DavidH; 22.03.2012