Java中23种面试常考的设计模式之备忘录模式(Memento)---行为型模式

简介: Java中23种面试常考的设计模式之备忘录模式(Memento)---行为型模式

Java中23种面试常考的设计模式之备忘录模式(Memento)

之前我们讲过的设计模式在这里呦:
【面试最常见的设计模式之单例模式】
【面试最常见的设计模式之工厂模式】
接下来我们要进行学习的是:备忘录模式。

备忘录模式

备忘录模式(Memento Pattern)保存一个对象的某个状态,以便在适当的时候恢复对象。备忘录模式属于行为型模式。

生产生活中常用的使用场景

  1. 各种应用软件中,存档历史记录。
  2. 管理系统中,消息撤回功能。
  3. 棋类游戏中,悔棋。
  4. 普通软件中,撤销操作。
  5. 数据库软件中,事务管理中的,回滚操作。
  6. 等等等等。。。。。。。。

备忘录模式优点与缺点

优点:

1、给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态。
2、实现了信息的封装,使得用户不需要关心状态的保存细节。

缺点:

消耗资源。如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存。

核心内容

备忘录模式使用三个类 Memento、Originator 和 CareTaker。Memento 包含了要被恢复的对象的状态。Originator 创建并在 Memento 对象中存储状态。Caretaker 对象负责从 Memento 中恢复对象的状态。

备忘录模式中的类 用途

源发起类Originator| 负责创建一个备忘录Memento,用以记录当前时刻它的内部状态,并可使用备忘录恢复内部状态
备忘录类Memento |负责存储Originator对象的内部状态,并可防止Originator以外的其他对象访问Memento
负责人类CareTaker| 负责保存好备忘录Memento

UML类图

image.png

具体代码实现

Games类:对应的就是我们的源发起类Originator

package com.memento;

/*
* Games 游戏类(对应的属性、构造方法、每走一步的保存操作、悔棋的操作、set方法、get方法)
*/
public class Games {
   
   

    private String gameName;

    private int curX;

    private int curY;

    public Games(){
   
   }

    public Games(String gameName,int curX,int curY){
   
   
        this.gameName=gameName;
        this.curX=curX;
        this.curY=curY;
    }

    // 保存记录
    public GamesMemento saveMemento(){
   
   
        return new GamesMemento(this);
    }

    // 恢复记录
    public void recovery(GamesMemento gamesMemento){
   
   
        this.gameName=gamesMemento.getGameName();
        this.curX=gamesMemento.getCurX();
        this.curY=gamesMemento.getCurY();
    }

    public void setGameName(String gameName){
   
   
        this.gameName=gameName;
    }

    public String getGameName(){
   
   
        return this.gameName;
    }


    public void setCurX(Integer curX){
   
   
        this.curX=curX;
    }

    public Integer getCurX(){
   
   
        return this.curX;
    }

    public void setCurY(Integer curY){
   
   
        this.curY=curY;
    }

    public Integer getCurY(){
   
   
        return this.curY;
    }

    public String toString(){
   
   
        return "象棋棋子向X方向移动:"+this.curX+"  象棋棋子向Y方向移动:"+this.curY;
    }
}

GamesMemento类:对应的就是我们的备忘录类Memento

package com.memento;

/*
* GamesMemento 游戏的存储记录类
*/
public class GamesMemento {
   
   

    private String gameName;

    private int curX;

    private int curY;


    public GamesMemento(){
   
   }

    public GamesMemento(String gameName,Integer curX,Integer curY){
   
   
        this.gameName=gameName;
        this.curX=curX;
        this.curY=curY;
    }


    public GamesMemento(Games games){
   
   
        this.gameName=games.getGameName();
        this.curX=games.getCurX();
        this.curY=games.getCurY();
    }

    public void setGameName(String gameName){
   
   
        this.gameName=gameName;
    }

    public String getGameName(){
   
   
        return this.gameName;
    }


    public void setCurX(Integer curX){
   
   
        this.curX=curX;
    }

    public Integer getCurX(){
   
   
        return this.curX;
    }

    public void setCurY(Integer curY){
   
   
        this.curY=curY;
    }

    public Integer getCurY(){
   
   
        return this.curY;
    }
}

GamesMementoManagement类:对应的就是我们的负责人类CareTaker

package com.memento;

/*
* GamesMementoManagement 管理我们的存储记录类
* 这个类是支持扩展的,如果想要保存多个状态,那么我们可以通过集合来记录每一个游戏中保存的状态
*/
public class GamesMementoManagement {
   
   


    private GamesMemento gamesMemento;


    public void setGamesMemento(GamesMemento gamesMemento){
   
   
        this.gamesMemento=gamesMemento;
    }


    public GamesMemento getGamesMemento(){
   
   
        return this.gamesMemento;
    }

}

测试类:

package com.memento;

public class Main {
   
   

    public static void main(String[] args){
   
   
        // 先创建我们的记录管理类
        GamesMementoManagement gamesMementoManagement=new GamesMementoManagement();
        Games games=new Games("象棋大战",4,6);
        System.out.println(games);
        GamesMemento gamesMemento=games.saveMemento();
        gamesMementoManagement.setGamesMemento(gamesMemento);

        games=new Games("象棋大战",5,9);
        System.out.println(games);
        System.out.println("此时走错了,想悔棋啦。。。。。。");
        games.recovery(gamesMementoManagement.getGamesMemento());
        System.out.println("悔棋成功,回到了最起初保存的状态!!!");
        System.out.println(games);
    }
}

运行结果截图:

image.png

相关文章
|
4月前
|
存储 缓存 算法
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
本文介绍了多线程环境下的几个关键概念,包括时间片、超线程、上下文切换及其影响因素,以及线程调度的两种方式——抢占式调度和协同式调度。文章还讨论了减少上下文切换次数以提高多线程程序效率的方法,如无锁并发编程、使用CAS算法等,并提出了合理的线程数量配置策略,以平衡CPU利用率和线程切换开销。
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
|
4月前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
4月前
|
设计模式 消息中间件 搜索推荐
Java 设计模式——观察者模式:从优衣库不使用新疆棉事件看系统的动态响应
【11月更文挑战第17天】观察者模式是一种行为设计模式,定义了一对多的依赖关系,使多个观察者对象能直接监听并响应某一主题对象的状态变化。本文介绍了观察者模式的基本概念、商业系统中的应用实例,如优衣库事件中各相关方的动态响应,以及模式的优势和实际系统设计中的应用建议,包括事件驱动架构和消息队列的使用。
|
4月前
|
设计模式 Java 数据库连接
Java编程中的设计模式:单例模式的深度剖析
【10月更文挑战第41天】本文深入探讨了Java中广泛使用的单例设计模式,旨在通过简明扼要的语言和实际示例,帮助读者理解其核心原理和应用。文章将介绍单例模式的重要性、实现方式以及在实际应用中如何优雅地处理多线程问题。
62 4
|
4月前
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
110 4
|
5月前
|
设计模式 Java 程序员
[Java]23种设计模式
本文介绍了设计模式的概念及其七大原则,强调了设计模式在提高代码重用性、可读性、可扩展性和可靠性方面的作用。文章还简要概述了23种设计模式,并提供了进一步学习的资源链接。
100 0
[Java]23种设计模式
|
4月前
|
设计模式 JavaScript Java
Java设计模式:建造者模式详解
建造者模式是一种创建型设计模式,通过将复杂对象的构建过程与表示分离,使得相同的构建过程可以创建不同的表示。本文详细介绍了建造者模式的原理、背景、应用场景及实际Demo,帮助读者更好地理解和应用这一模式。
126 0
|
5月前
|
算法 Java 数据中心
探讨面试常见问题雪花算法、时钟回拨问题,java中优雅的实现方式
【10月更文挑战第2天】在大数据量系统中,分布式ID生成是一个关键问题。为了保证在分布式环境下生成的ID唯一、有序且高效,业界提出了多种解决方案,其中雪花算法(Snowflake Algorithm)是一种广泛应用的分布式ID生成算法。本文将详细介绍雪花算法的原理、实现及其处理时钟回拨问题的方法,并提供Java代码示例。
172 2
|
5月前
|
设计模式 监控 算法
Java设计模式梳理:行为型模式(策略,观察者等)
本文详细介绍了Java设计模式中的行为型模式,包括策略模式、观察者模式、责任链模式、模板方法模式和状态模式。通过具体示例代码,深入浅出地讲解了每种模式的应用场景与实现方式。例如,策略模式通过定义一系列算法让客户端在运行时选择所需算法;观察者模式则让多个观察者对象同时监听某一个主题对象,实现松耦合的消息传递机制。此外,还探讨了这些模式与实际开发中的联系,帮助读者更好地理解和应用设计模式,提升代码质量。
Java设计模式梳理:行为型模式(策略,观察者等)
|
5月前
|
设计模式 Java
Java设计模式
Java设计模式
60 0