备忘录模式

介绍

**定义:**在不破坏封装的前提下, 捕获一个对象的内部状态并在该对象之外进行保存, 使得客户端可以在之后的某个节点将对象恢复到原先保存的状态. 备忘录模式提供了一种对象状态的撤销机制, 当系统中某个对象需要恢复到某一历史状态时就可以使用备忘录模式进行设计.

UML

示例

java 复制代码
package com.sumlv.demo;

import com.sumlv.demo.entity.Order;
import com.sumlv.demo.entity.Result;
import com.sumlv.demo.enumeration.OrderState;
import com.sumlv.demo.service.OrderService;
import com.sumlv.demo.service.impl.OrderServiceImpl;

import java.math.BigDecimal;

public class Main {

    public static void main(String[] args) {
        OrderService service = new OrderServiceImpl();
        Order order = new Order(
                1L,
                2L,
                3L,
                new BigDecimal("100.00"),
                OrderState.PENDING,
                null
        );

        Result<Order> result = service.payOrder(order);
        order = result.getData();
        System.out.println(result);
        System.out.println(order);

        System.out.println("========================================================");

        if (result.getSuccess()) {
            result = service.doProduce(order);
            order = result.getData();
            System.out.println(result);
            System.out.println(order);
        }
    }

}
java 复制代码
package com.sumlv.demo.service;

import com.sumlv.demo.entity.Order;
import com.sumlv.demo.entity.Result;

/**
 * 订单服务
 *
 * @Auther: yuzhuo.song
 * @Date: 2026-03-26
 */
public interface OrderService {

    /**
     * 支付订单
     *
     * @param order 订单信息
     * @return 支付结果
     */
    Result<Order> payOrder(Order order);

    /**
     * 执行生产
     *
     * @param order 订单信息
     * @return 生产结果
     */
    Result<Order> doProduce(Order order);

}
java 复制代码
package com.sumlv.demo.service.impl;

import com.sumlv.demo.entity.Order;
import com.sumlv.demo.entity.Result;
import com.sumlv.demo.enumeration.OrderState;
import com.sumlv.demo.memento.OrderMemento;
import com.sumlv.demo.service.OrderService;

/**
 * 订单服务实现
 *
 * @Auther: yuzhuo.song
 * @Date: 2026-03-26
 */
public class OrderServiceImpl implements OrderService {

    @Override
    public Result<Order> payOrder(Order order) {
        OrderMemento memento = order.createMemento();

        try {
            // 此处省略具体支付逻辑
            order.setState(OrderState.PROCESSING);

            return Result.buildSuccessResult(order);
        } catch (Throwable t) {
            // 此处省略具体回滚逻辑
            order.restoreMemento(memento);

            return Result.buildFailResult(order, t.getMessage());
        }
    }

    @Override
    public Result<Order> doProduce(Order order) {
        OrderMemento memento = order.createMemento();

        try {
            // 此处省略具体生产逻辑
            order.setState(OrderState.SUCCESS);

            int error = 1 / 0;

            return Result.buildSuccessResult(order);
        } catch (Throwable t) {
            // 此处省略具体回滚逻辑
            order.restoreMemento(memento);

            return Result.buildFailResult(order, t.getMessage());
        }
    }

}
java 复制代码
package com.sumlv.demo.entity;

import com.sumlv.demo.enumeration.OrderState;
import com.sumlv.demo.memento.OrderMemento;

import java.math.BigDecimal;

/**
 * 订单
 *
 * @Auther: yuzhuo.song
 * @Date: 2026-03-26
 */
public class Order {

    private Long treadId;

    private Long userId;

    private Long productId;

    private BigDecimal price;

    private OrderState state;

    private String remark;

    public OrderMemento createMemento() {
        System.out.println("执行备忘录创建");

        return new OrderMemento(
                this.treadId,
                this.userId,
                this.productId,
                this.price,
                this.state,
                this.remark
        );
    }

    public void restoreMemento(OrderMemento memento) {
        System.out.println("执行备忘录恢复");

        this.treadId = memento.getTreadId();
        this.userId = memento.getUserId();
        this.productId = memento.getProductId();
        this.price = memento.getPrice();
        this.state = memento.getState();
        this.remark = memento.getRemark();
    }

    public Long getTreadId() {
        return treadId;
    }

    public void setTreadId(Long treadId) {
        this.treadId = treadId;
    }

    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public Long getProductId() {
        return productId;
    }

    public void setProductId(Long productId) {
        this.productId = productId;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    public OrderState getState() {
        return state;
    }

    public void setState(OrderState state) {
        this.state = state;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    @Override
    public String toString() {
        return "Order{" +
                "treadId=" + treadId +
                ", userId=" + userId +
                ", productId=" + productId +
                ", price=" + price +
                ", state=" + state +
                ", remark='" + remark + '\'' +
                '}';
    }

    public Order(Long treadId, Long userId, Long productId, BigDecimal price, OrderState state, String remark) {
        this.treadId = treadId;
        this.userId = userId;
        this.productId = productId;
        this.price = price;
        this.state = state;
        this.remark = remark;
    }

}
java 复制代码
package com.sumlv.demo.memento;

import com.sumlv.demo.enumeration.OrderState;

import java.math.BigDecimal;

/**
 * 订单备忘录
 *
 * @Auther: yuzhuo.song
 * @Date: 2026-03-26
 */
public class OrderMemento {

    private final Long treadId;

    private final Long userId;

    private final Long productId;

    private final BigDecimal price;

    private final OrderState state;

    private final String remark;

    public Long getTreadId() {
        return treadId;
    }

    public Long getUserId() {
        return userId;
    }

    public Long getProductId() {
        return productId;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public OrderState getState() {
        return state;
    }

    public String getRemark() {
        return remark;
    }

    public OrderMemento(Long treadId, Long userId, Long productId, BigDecimal price, OrderState state, String remark) {
        this.treadId = treadId;
        this.userId = userId;
        this.productId = productId;
        this.price = price;
        this.state = state;
        this.remark = remark;
    }

}
java 复制代码
package com.sumlv.demo.enumeration;

/**
 * 订单状态
 *
 * @Auther: yuzhuo.song
 * @Date: 2026-03-26
 */
public enum OrderState {

    /**
     * 待支付
     */
    PENDING,

    /**
     * 处理中
     */
    PROCESSING,

    /**
     * 生产成功
     */
    SUCCESS,

    /**
     * 生产失败
     */
    FAILED;

}
java 复制代码
package com.sumlv.demo.entity;

import java.io.Serializable;

/**
 * 请求结果集
 *
 * @Auther: yuzhuo.song
 * @Date: 2026-03-26
 */
public class Result<T> implements Serializable {

    private Boolean success;

    private String code;

    private String message;

    private T data;

    public static <T> Result<T> buildSuccessResult(T data, String message) {
        return new Result<>(
                Boolean.TRUE,
                ResultCodeConstant.SUCCESS_CODE,
                message,
                data
        );
    }

    public static <T> Result<T> buildSuccessResult(T data) {
        return new Result<>(
                data,
                Boolean.TRUE,
                ResultCodeConstant.SUCCESS_CODE
        );
    }

    public static Result<?> buildSuccessResult() {
        return new Result<>(
                Boolean.TRUE,
                ResultCodeConstant.SUCCESS_CODE
        );
    }

    public static <T> Result<T> buildFailResult(String code, String message, T data) {
        return new Result<>(
                Boolean.FALSE,
                code,
                message,
                data
        );
    }

    public static Result<?> buildFailResult(String code, String message) {
        return new Result<>(
                Boolean.FALSE,
                code,
                message
        );
    }

    public static <T> Result<T> buildFailResult(T data, String message) {
        return new Result<>(
                Boolean.FALSE,
                ResultCodeConstant.FAIL_CODE,
                message,
                data
        );
    }

    public static Result<?> buildFailResult(String message) {
        return new Result<>(
                Boolean.FALSE,
                ResultCodeConstant.FAIL_CODE,
                message
        );
    }

    public Boolean getSuccess() {
        return success;
    }

    public void setSuccess(Boolean success) {
        this.success = success;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    @Override
    public String toString() {
        return "Result{" +
                "success=" + success +
                ", code='" + code + '\'' +
                ", message='" + message + '\'' +
                ", data=" + data +
                '}';
    }

    public Result(Boolean success, String code, String message, T data) {
        this.success = success;
        this.code = code;
        this.message = message;
        this.data = data;
    }

    public Result(Boolean success, String code, String message) {
        this(success, code, message, null);
    }

    public Result(T data, Boolean success, String code) {
        this(success, code, null, data);
    }

    public Result(Boolean success, String code) {
        this(success, code, null);
    }

    /**
     * 返回状态码常量
     */
    public static class ResultCodeConstant {

        /**
         * 成功状态码
         */
        public static final String SUCCESS_CODE = "200";

        /**
         * 失败状态码
         */
        public static final String FAIL_CODE = "500";
        
    }

}

总结

使用场景

  1. 当需要保存某一对象的瞬时状态时.

优点:

  1. 提供了一种状态恢复机制, 使用户可以在需要的时候方便的恢复到某个特定的历史状态;

  2. 实现了对快照对象的信息封装, 使其在创建后不会被其他代码所修改.

缺点:

  1. 当备忘录对象本身过大或使用集合方式频繁保存备忘录对象时, 会对系统空间造成较大负担.
相关推荐
郝学胜-神的一滴10 天前
C++备忘录模式:优雅实现对象状态保存与恢复
开发语言·c++·程序人生·备忘录模式
逆境不可逃12 天前
【从零入门23种设计模式18】行为型之备忘录模式
服务器·数据库·设计模式·oracle·职场和发展·迭代器模式·备忘录模式
驴儿响叮当20101 个月前
设计模式之备忘录模式
设计模式·备忘录模式
J_liaty1 个月前
23种设计模式一备忘录模式
设计模式·备忘录模式
geovindu1 个月前
python: Memento Pattern
开发语言·python·设计模式·备忘录模式
day day-up2 个月前
公考成语积累
备忘录模式
apolloyhl2 个月前
Memento 备忘录模式
备忘录模式
懵萌长颈鹿2 个月前
备忘录模式 (Memento Pattern)
备忘录模式
Engineer邓祥浩2 个月前
设计模式学习(21) 23-19 备忘录模式
学习·设计模式·备忘录模式