当前位置: 首页 > wzjs >正文

网站开发数据库技术优秀营销案例分享

网站开发数据库技术,优秀营销案例分享,谷歌浏览器app,优化营商环境的措施建议对备忘录模式的理解 一、场景1、题目【[来源](https://kamacoder.com/problempage.php?pid1095)】1.1 题目描述1.2 输入描述1.3 输出描述1.4 输入示例1.5 输出示例 2、理解需求 二、不采用备忘录设计模式1、代码2、问题3、错误的备忘录模式 三、采用备忘录设计模式1、代码1.1 …

对备忘录模式的理解

    • 一、场景
      • 1、题目【[来源](https://kamacoder.com/problempage.php?pid=1095)】
        • 1.1 题目描述
        • 1.2 输入描述
        • 1.3 输出描述
        • 1.4 输入示例
        • 1.5 输出示例
      • 2、理解需求
    • 二、不采用备忘录设计模式
      • 1、代码
      • 2、问题
      • 3、错误的备忘录模式
    • 三、采用备忘录设计模式
      • 1、代码
        • 1.1 Originator(原发器)
        • 1.2 Memento(备忘录)
        • 1.3 Caretaker(负责人)
        • 1.4 客户端
      • 2、思考

一、场景

1、题目【来源】

1.1 题目描述

小明正在设计一个简单的计数器应用,支持增加(Increment)和减少(Decrement)操作,以及撤销(Undo)和重做(Redo)操作,请你使用备忘录模式帮他实现。

1.2 输入描述

输入包含若干行,每行包含一个字符串,表示计数器应用的操作,操作包括 “Increment”、“Decrement”、“Undo” 和 “Redo”。

1.3 输出描述

对于每个 “Increment” 和 “Decrement” 操作,输出当前计数器的值,计数器数值从0开始 对于每个 “Undo” 操作,输出撤销后的计数器值。 对于每个 “Redo” 操作,输出重做后的计数器值。

1.4 输入示例
Increment
Increment
Decrement
Undo
Redo
Increment
1.5 输出示例
1
2
1
2
1
2

2、理解需求

  • 增加(Increment)和减少(Decrement)操作比较好理解,不赘述了。

  • 重点理解下:撤销(Undo)和重做(Redo)操作。

    image

    • 一般编辑器,都支持Undo和Redo操作。

    • Undo操作:因为操作导致值发生变化,例如,0变成1。我们需要记下变化的值,这样才方便用户回退。

      • 很明显,应该用栈来记录。例如:0 -> 1 -> 2 -> 3。 当前处于3,接下来Undo,应该从3变成2。也就是把3从栈中弹出。
    • Redo操作:依然基于“0 -> 1 -> 2 -> 3”进行说明,当前处于3,用户Undo后,3变成2,接下来,用户Redo了,也就是希望2又变回3。

      • 也就是,我们需要记录Undo栈中弹出来的值。很显然,也是一个栈。

二、不采用备忘录设计模式

1、代码

public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int res = 0;// 栈Deque<Integer> undoStack = new ArrayDeque<>();undoStack.push(res);Deque<Integer> redoStack = new ArrayDeque<>();while (scanner.hasNextLine()) {String command = scanner.nextLine();res = runCommand(command, res, undoStack, redoStack);System.out.println(res);}}private static Integer runCommand(String command, Integer res, Deque<Integer> undoStack, Deque<Integer> redoStack) {if ("Increment".equals(command)) {res += 1;undoStack.push(res);return res;} else if ("Decrement".equals(command)) {res -= 1;undoStack.push(res);return res;} else if ("Undo".equals(command)) {if (undoStack.size() == 1) {// 相当于还没有做任何操作,用户就执行了Undoreturn undoStack.peek();} else if (undoStack.size() > 1) {Integer value = undoStack.pop();redoStack.push(value);return undoStack.peek();}} else if ("Redo".equals(command)) {if (!redoStack.isEmpty()) {Integer value = redoStack.pop();undoStack.push(value);return value;}}return res;}
}

2、问题

  • Increment等操作是客户端(main方法)的命令,客户端不应该看到undoStack、redoStack等数据。

    • 上面的写法是典型的面向过程开发,我们需要使用面向对象开发。

      image

  • 很显然,我们需要设计一个Calculator。

    • public class Calculator {private int value;public Calculator() {this.value = 0;}public Integer runCommand(String command) {return null;}
      }public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);Calculator calculator = new Calculator();while (scanner.hasNextLine()) {String command = scanner.nextLine();Integer res = calculator.runCommand(command);System.out.println(res);}}
      }
      
  • 为了实现Undo、Redo,这个类的对象有一个特点,需要保存和恢复对象之前的状态。

    • 备忘录模式是一种行为设计模式, 允许在不暴露对象实现细节的情况下保存和恢复对象之前的状态。[先有场景,后有设计模式]

3、错误的备忘录模式

public class Calculator {private int value;private Deque<Integer> undoStack;private Deque<Integer> redoStack;public Calculator() {this.value = 0;this.undoStack = new ArrayDeque<>();undoStack.push(value);this.redoStack = new ArrayDeque<>();}public Integer runCommand(String command) {if ("Increment".equals(command)) {value += 1;undoStack.push(value);return value;} else if ("Decrement".equals(command)) {value -= 1;undoStack.push(value);return value;} else if ("Undo".equals(command)) {if (undoStack.size() == 1) {// 相当于还没有做任何操作,用户就执行了Undoreturn undoStack.peek();} else if (undoStack.size() > 1) {Integer v = undoStack.pop();redoStack.push(v);return undoStack.peek();}} else if ("Redo".equals(command)) {if (!redoStack.isEmpty()) {Integer v = redoStack.pop();undoStack.push(v);return v;}}return value;}
}
  • Calculator这个类是违背单一职责的,按照备忘录模式的经典设计,应该具有3个角色:

    • Originator(原发器):状态持有者,并且可以请求保存状态和恢复状态。
    • Memento(备忘录):负责保存状态和恢复状态。
    • Caretaker(负责人):负责管理备忘录。

三、采用备忘录设计模式

1、代码

1.1 Originator(原发器)
public class Counter {private int value;public Counter() {this.value = 0;}public int getValue() {return value;}public void increment() {this.value++;}public void decrement() {this.value--;}public Memento createMemento() {return new Memento(this.value);}public void restoreMemento(Memento memento) {this.value = memento.getValue();}
}
1.2 Memento(备忘录)
public class Memento {private int value;public Memento(int value) {this.value = value;}public int getValue() {return value;}
}
1.3 Caretaker(负责人)
public class Calculator {private Counter counter;private Deque<Memento> undoStack;private Deque<Memento> redoStack;public Calculator() {counter = new Counter();undoStack = new ArrayDeque<>();redoStack = new ArrayDeque<>();}public Integer runCommand(String command) {if (command.equals("Increment")) {counter.increment();undoStack.push(counter.createMemento());redoStack.clear(); // redoStack是专门用来记录undoStack弹出的状态的,undoStack放入新状态后,redoStack里面的状态就无效了} else if (command.equals("Decrement")) {counter.decrement();undoStack.push(counter.createMemento());redoStack.clear();} else if (command.equals("Undo")) {if (!undoStack.isEmpty()) {Memento memento = undoStack.pop();redoStack.push(memento);counter.restoreMemento(undoStack.peek());}} else if (command.equals("Redo")) {if (!redoStack.isEmpty()) {Memento memento = redoStack.pop();counter.restoreMemento(memento);undoStack.push(memento);}} else {throw new RuntimeException("Unknown command");}return counter.getValue();}
}
1.4 客户端
public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);Calculator calculator = new Calculator();while (scanner.hasNextLine()) {String command = scanner.nextLine();Integer res = calculator.runCommand(command);System.out.println(res);}}
}

2、思考

  • 相比“3、错误的备忘录模式”,每个类的职责更单一一些。但,Memento好麻烦啊。相当于把Counter的字段复制了一遍。以后Counter加一个字段,Memento就要补一个字段。太麻烦了。

  • 一种不错的解决办法是:序列化。

  • public class Counter {private int value;public Counter() {}public void setValue(int value) {this.value = value;}public int getValue() {return value;}public void increment() {this.value++;}public void decrement() {this.value--;}public void restoreMemento(Memento memento) {String backup = memento.getBackup();Counter tmpCounter = JSON.parseObject(backup, Counter.class);this.value = tmpCounter.value;}public Memento createMemento() {String backup = JSON.toJSONString(this);return new Memento(backup);}
    }public class Memento {private String backup;public Memento(String backup) {this.backup = backup;}public String getBackup() {return this.backup;}
    }
    
http://www.dtcms.com/wzjs/563528.html

相关文章:

  • 可以做系统同步时间的网站设计制作散发寄递销售展示使用
  • 东昌网站建设北票市建设工程安全管理站网站
  • 建设网站基础电子烟网站设计
  • 建设网站费用计入什么费用微信对接网站可以做301跳转吗
  • 丽江建设工程信息网站国家高新技术企业证书图片
  • 北京市建设公租房网站局域网做网站 内网穿透
  • 团队网站建设哪家便宜许昌小学网站建设
  • 杭州网站开发平均工资广州天河区做网站的公司
  • 山东济南做网站公司管理咨询公司需要的能力
  • 邯郸网站制wordpress qq 群
  • 网站升级维护期间能访问吗wordpress 嵌入地图
  • 北京有哪些炫酷的网站页面论述三种常见的网络营销方式
  • discuz网站名称注册公司最少需要多少钱
  • wordpress角色权限管理seo优化知识总结
  • 福州市建网站公司软文推广名词解释
  • 公司网站页面设计项目建设综述
  • 如何利用社交网站做招聘最新军事新闻热点事件
  • 台州建设工程网站小程序开发怎么做
  • 丝绸之路网站建设pc下载网
  • 京东网站的设计特点怎样建立商贸网站
  • 建设产品网站课程设计找网页设计公司去哪个平台
  • 网站建设需求登记表网页设计基础教学设计及ppt
  • 上海哪个区最繁华seo原创工具
  • 做网站 上海店面设计案例分析
  • 科技设计网站有哪些什么网站可以做私房菜外卖
  • 中国建设工程信息网官网建造师查询李勇seo的博客
  • angularjs的网站模板四川省建设厅的注册中心网站首页
  • 服务网站建设企业wordpress调用登录logo
  • 免费的推文制作网站美妆网页设计素材
  • 商城开发网站开发网页设计图片