Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 500|回复: 0

[设计模式学习]双重接口的实现,备忘录模式

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-10-28 23:57:19 | 显示全部楼层 |阅读模式
    一、定义:备忘录(memento)模式又叫快照(snapshot)模式或者token模式,主要功能:
          备忘录模式是用一个对象来存储另外一个对象的内部状态的快照,实现备忘录模式的关键点是在不破坏封装的情况下,将一个对象的状态捕捉住,并外部化,存储起来,从而可以在合适的时候,把这个对象还原。

    说明:备忘录模式是模式中比较好理解的一个,这里就不举例子,但是备忘录模式是模式中实现比较难,或者说实现比较巧的,这里主要说说。

    二、备忘录模式的实现
    1,备忘录模式中的角色
    发起人:创建含有内部状态的备忘录对象,并使用备忘录
                  对象存储状态

    负责人:负责人保存备忘录对象,但不检查备忘录对象的内容

    备忘录:备忘录对象将发起人对象的内部状态存起来,并保正其内容不被发起人对象之外的对象像读取  
      
      
    1. 注意:
    2.     在备忘录的角色中,定义了他必须对不同的人提供不同的接口,对发起人提供宽接口,对其它任何人提供窄接口。
    3. 也许你说我都提供宽接口得了。对这也是备忘录的一种实现,叫做白箱备忘录,不过这种方法的封装没有设计好,安全性不够好。
    4. 2,白箱备忘录的实现:
    复制代码

       
         1
       
       
        public
         
        class
         Originator
       
        {
      2    private String state;
      3    public Memento CreateMemento(){
      4        return new Memento(state);
      5    }
      6    public void restoreMemento(Memento memento){
      7        this.state = memento.getState();
      8    }
      9    public String getState(){
    10        return this.state;
    11    }
    12    public void setState(String state){
    13        this.state=state;
    14        System.out.println("Current state = " + this.state);
    15    }
    16}
       

        17
       
        public
         
        class
         Memento
       
        {
    18    private String state;
    19    public Memento(String state){
    20        this.state = state;
    21    }
    22    public String getState(){
    23        return this.state;
    24    }
    25    public void setState(){
    26        this.state = state;
    27    }
    28}
       

        29
       
        public
         
        class
         Caretaker
       
        {
    30    private Memento memento;
    31    public Memento retrieveMemento(){
    32        return this.memento;
    33    }
    34    public void saveMemento(Memento memento){
    35        this.memento = memento;
    36    }
    37}
       

        38
       
        public
         
        class
         Client
       
        {
    39    private static Originator o = new Originator();
    40    private static Caretaker c = new Caretaker();
    41    public static void main(Sting[] args){
    42        o.setState("ON");
    43        c.saveMemento(o.createMemento());
    44        o.setState("OFF");
    45        o.restoreMemento(c.retrieveMemento());
    46    }
    47}
       
    白箱的优点:实现简单
    白箱的缺点:上边说了,破坏了封装,安全性有些问题。
    说明:这里白箱的实现只保存了一个状态,其实是可以保存多个状态的。

    3,双接口的实现,宽窄接口(黑箱)
    如何实现宽窄接口呢,内部类也许是个好方法。我们把备忘录类设计"成发起人"的内部类,但这样还有的问题是同一
    package中的其它类也能访问到,为了解决这个问题,我们可以把"备忘录"的方法设计成私有的方法,这样就
    可以保正封装,又保正发起人能访问到。实现如下:
    定义窄接口
    .

       
         1
       
       
        public
         
        interface
         NarrowMemento
       
        {
      2    public void narrowMethod();
      3}
       

         4
       
        class
         Originator
       
        {
      5    private String state;
      6    private NarrowMemento memento;
      7    public Originator(){
      8    }
      9    public NarrowMemento createMemento(){
    10        memento = new Memento(this.state);
    11        return memento;
    12    }
    13    public void restoreMemento(NarrowMemento memento){
    14        Memento aMemento = (Memento)memento;
    15        this.setState(aMemento.getState());
    16    }
    17    public String getState(){
    18        return this.state;
    19    }
    20    public void setState(String state){
    21        this.state = state;
    22    }
    23    //内部类
    24    protected class Memento implements NarrowMemento{
    25        private String savedState;
    26        private Memento(String someState){
    27            saveState = someState;
    28        }
    29        private void setState(String someState){
    30            saveState = someState;
    31        }
    32        private String getState(){
    33            return saveState;
    34        }
    35        public void narrowMethod(){
    36            System.out.println("this is narrow method");
    37        }
    38        
    39    }
    40    public NarrowMemento getNarrowMemento(){
    41        return memento;
    42    }
    43}
       

        44
       
        public
         
        class
         Caretaker
       
        {
    45    private NarrowMemento memento;
    46    public NarrowMemento retrieveMemento(){
    47        return this.memento;
    48    }
    49    public void saveMemento(NarrowMemento memento){
    50        this.memento = memento;
    51    }
    52}
       

        53
       
        public
         
        class
         Client
       
        {
    54    private static Originator o = new Originator();
    55    private static Caretaker c = new Caretaker();
    56    public static void main(String[] args){
    57        //use wide interface
    58        o.setState("On");
    59        c.saveMemento(o.createMemento());
    60        o.setState("Off");
    61        o.restoreMemento(c.retrieveMemento());
    62        //use narrow interface
    63        NarrowMemento memento = o.getNarrowMemento();
    64        memento.narrowMethod();
    65        
    66    }
    67}
        ok,实现了对大多数人实现比较窄的接口,对Originator实现了宽接口.

    三,最后的一些说明:
    1,前边两个例子都是记录了单个状态(单check点),要实现多个状态点很容易,只须要把记录state的字符串换
    成一个list,然後添加,取得。如果须要随机须得状态点,也可以用map来存放.这样多个check点就实现了。
    2,一般情况下可以扩展负责人的功能,让负责人的功能更强大,从而让客户端的操做更少些。解放客户端。
    3,自述历史模式,这个就是把发起人,负责人写在一个类中,平时的应用中这种方法比较常见。
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-26 01:30 , Processed in 0.421707 second(s), 34 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表