介绍
**定义:**在不破坏封装的前提下, 捕获一个对象的内部状态并在该对象之外进行保存, 使得客户端可以在之后的某个节点将对象恢复到原先保存的状态. 备忘录模式提供了一种对象状态的撤销机制, 当系统中某个对象需要恢复到某一历史状态时就可以使用备忘录模式进行设计.
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";
}
}
总结
使用场景
- 当需要保存某一对象的瞬时状态时.
优点:
-
提供了一种状态恢复机制, 使用户可以在需要的时候方便的恢复到某个特定的历史状态;
-
实现了对快照对象的信息封装, 使其在创建后不会被其他代码所修改.
缺点:
- 当备忘录对象本身过大或使用集合方式频繁保存备忘录对象时, 会对系统空间造成较大负担.