备忘录模式
备忘录模式(Memento Pattern)保存一个对象的某个状态,以便在适当的时候恢复对象。备忘录模式属于行为型模式。
破坏类的封装性,将类的一部分属性或者全部属性封装起来,然后存储起来方便恢复这些状态。
备忘录模式使用三个类 Memento、Originator 和 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内部类,实现接口里面的方法,除了方法里面提供的访问参数,其余的均不予提供访问。
也命名为 窄接口。