Alt_Shift

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

备忘录模式

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

破坏类的封装性,将类的一部分属性或者全部属性封装起来,然后存储起来方便恢复这些状态。

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

自己设计了一个留言系统

Originator

1 package design_mode.momento;
 2 
 3 public class ChatMessage {
 4     String chatMessage;
 5     String date;
 6 
 7     public void setChatMessage(String chatMessage) {
 8         this.chatMessage = chatMessage;
 9     }
10 
11     public ChatMessage(String chatMessage, String date){
12         this.chatMessage = chatMessage;
13         this.date = date;
14     }
15     public MessageMomento save(){
16         return new MessageMomento(chatMessage, date);
17     }
18 
19     public void restore(MessageMomento messageMomento){
20         this.chatMessage = messageMomento.message;
21         this.date = messageMomento.date;
22     }
23 
24     public void show(){
25         System.out.println("我说了:" + chatMessage + " 时间:" + date);
26     }
27 }

 

Momento

 1 package design_mode.momento;
 2 
 3 public class MessageMomento {
 4     String message;
 5     String date;
 6     public MessageMomento(String message, String date){
 7         this.message = message;
 8         this.date = date;
 9     }
10 }

 

CareTaker

package design_mode.momento;

import java.util.ArrayList;

public class MomentoControl {
    private static ArrayList<MessageMomento> record ;
    public MomentoControl(){
        record = new ArrayList<MessageMomento>();
    }
    public MessageMomento getMessage(int index){
        return record.get(index);
    }
    public void addMessage(MessageMomento messageMomento){
        record.add(messageMomento);
    }

}

 

Demo测试

 

 1 package design_mode.momento;
 2 
 3 import java.io.BufferedReader;
 4 import java.io.IOException;
 5 import java.io.InputStreamReader;
 6 import java.util.Date;
 7 /**
 8  * 备忘录模式,将展示对象的全部状态或者部分状态拿出来封装成一个存储对象,
 9  * 备忘录中用数组链表存储 存储对象  使用时定义浮标,用浮标的移动来撤销
10  */
11 
12 public class MomentoDemo {
13     public static MomentoControl mc = new MomentoControl();
14     static int index = -1;
15 
16     public static void main(String[] args) throws IOException{
17 
18         String message = firstPlace();
19         Date date = new Date();
20         ChatMessage chatMessage = new ChatMessage(message,
21                 String.valueOf(date));
22         send(chatMessage);
23         chatMessage.setChatMessage("hello again");
24         send(chatMessage);
25         undo(chatMessage, index);
26     }
27     public static String firstPlace() throws IOException {
28         System.out.println("请输入你想说的:");
29         String message =
30                 (new BufferedReader(new InputStreamReader(System.in))).readLine();
31         return message;
32     }
33     public static void send(ChatMessage chatMessage){
34         MessageMomento messageMomento = chatMessage.save();
35         index ++;
36         mc.addMessage(messageMomento);
37         chatMessage.show();
38     }
39     public static void  undo(ChatMessage chatMessage, int i){
40         System.out.println("---------撤销操作--------");
41         index --;
42         chatMessage.restore(mc.getMessage(i - 1));
43         chatMessage.show();
44     }
45 }


我说了:hello 时间:Sun Mar 15 11:41:05 CST 2020
我说了:hello again 时间:Sun Mar 15 11:41:05 CST 2020
---------撤销操作--------
我说了:hello 时间:Sun Mar 15 11:41:05 CST 2020

 

我jio得缺点还是挺明显的,资源消耗太大,如果创建的对象非常多,就需要更多的空间造成资源的浪费,还有就是上面的CareTaker对外是完全透明的,随意访问,这就是典型的白箱问题

黑箱

定义一个MomentoFace接口,定义想让外界访问的方法,然后将Momento类变成Originator的private内部类,实现接口里面的方法,除了方法里面提供的访问参数,其余的均不予提供访问。

也命名为 窄接口。

 

posted on 2020-03-15 13:00  Alt_Shift  阅读(179)  评论(0编辑  收藏  举报