十一大行为型模式之九:备忘录模式。java
姓名 :备忘录模式
英文名 :Memento Pattern
价值观 :凡事要有备份
我的介绍 :
Without violating encapsulation,capture and externalize an object's internal state so that the object can be restored to this state later.
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象以外保存这个状态。这样之后就可将该对象恢复到原先保存的状态。
(来自《设计模式之禅》)数据库
点开看这篇文章的各位,都是。。。程序界的大佬。做为程序猿,免不了『上线』这件小事。每逢上线必祭天。。。上线这件事咱们不少人都操做过,每家公司有不一样的上线流程以及上线的技术能力。按照发布的平台的完善程度大概分为 3 种。设计模式
上线
:备份并关闭应用、部署并启动新应用;回滚
:关闭新应用、恢复旧应用并启动。上线
:关闭旧应用、复制旧应用到备份空间、复制新应用到部署环境、启动新应用;回滚
:关闭新应用、删除新应用、从备份空间复制旧应用到部署环境、启动旧应用。其实经过发布平台完善程度能够侧面反映企业的技术成熟程度。怎么说呢?发布系统的操做难易程度在咱们做为程序猿心中,都有一个可接受的范围。假设刚开始是单体应用,一个 tomcat 和一个 war 就搞定,你须要发布平台么?并不须要,咱 ctrl+C
、ctrl+V
、shutdown
、startup
就行,还弄什么发布平台。当系统有多套服务时,每次上线都须要部署 10 个机器的应用,这时你能忍么?要是仍是手工操做,那发布一次系统得花费好长时间,要是再搞很差,回滚一次,一夜都没了;这时就会逼迫开发出一个简易的发布平台,把对多台机器的操做步骤放到发布平台上。当系统是以微服务的架构发展时,每一个服务都有上百个实例,那这时就不能简单的把操做步骤搬到发布平台了,还得简化步骤,最终变成上面说的 一键部署
和一键回滚
。tomcat
上面的 3 种我都亲身经历过。。。在刚出来实习时候,就经历了第 3 种状况,由于是单体应用,一个应用搞定全部东西,手动部署已知足要求。到了银行工做,接触到了云平台,那时就只须要一个按钮就唰唰唰的部署了,也是上面说的第 1 种。而如今,正在经历第 2 种发布平台,只是简单的把操做步骤搬到了系统上,目前的状况是机器愈来愈多,操做步骤没删减的话,每次发布会花费不少时间,这也会去促进开发出更方便使用的发布平台。服务器
回到今天的主题,今天讲的是备忘录模式,从字面上理解,就是讲备份东西,有了备份就能够恢复。上面讲了一大堆发布的东西,也是我们工做中接触蛮多的事情,发布的最核心就是要支持部署新应用
以及回滚老应用
,回滚特别重要,它可以保证在新应用出现异常的状况下,立刻恢复到旧应用可用的状态,减小异常的影响面。发布这东东也很符合备忘录模式,下面经过模拟发布步骤代码来说备忘录模式。这里讲的不是上面说的第 1 种,这里围绕着第 3 种发布步骤写,无论哪一种发布平台,它们的底层都是同样的。架构
先定义应用实例这个类,应用通常会有应用名、版本号信息。app
/** * 应用实例 */ class App { private String content; private String version; public App(String content, String version) { this.content = content; this.version = version; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public String getVersion() { return version; } public void setVersion(String version) { this.version = version; } @Override public String toString() { return "App{" + "content='" + content + '\'' + ", version='" + version + '\'' + '}'; } }
定义 AppBackup
来充当备忘录角色,它有一个属性就是 App
,也就是备份的应用。ide
/** * 应用备份(充当备忘录角色) */ class AppBackup { private App app; public AppBackup(App app) { this.app = app; } public App getApp() { return app; } public void setApp(App app) { this.app = app; } }
有了备忘录,也须要一个空间来存放备忘录,并对外提供备忘录。微服务
/** * 备份空间 */ class Space { private AppBackup appBackup; public AppBackup getAppBackup() { return appBackup; } public void setAppBackup(AppBackup appBackup) { this.appBackup = appBackup; } }
有了这些备份机制,还须要有一个程序猿来部署,这位同窗须要掌握发布步骤的全部过程,部署新应用以及回滚旧应用。学习
/** * 部署应用的同窗 */ class Deployer { // 要部署的应用 private App app; public App getApp() { return app; } // 设置部署应用 public void setApp(App app) { this.app = app; } // 建立应用的备份 public AppBackup createAppBackup() { return new AppBackup(app); } // 从备忘录恢复应用 public void setAppBackup(AppBackup appBackup) { this.app = appBackup.getApp(); } // 显示应用的信息 public void showApp() { System.out.println(this.app.toString()); } // 暂停应用 public void stopApp() { System.out.println("暂停应用:" + this.app.toString()); } // 启动应用 public void startApp() { System.out.println("启动应用:" + this.app.toString()); } }
再献上测试代码。
public class MementoTest { public static void main(String[] args) { Deployer deployer = new Deployer(); deployer.setApp(new App("apply-system", "1.0.0")); System.out.println("1. 暂停旧应用"); deployer.stopApp(); System.out.println("2. 备份旧应用"); Space space = new Space(); space.setAppBackup(deployer.createAppBackup()); System.out.println("3. 拷贝新应用到服务器"); deployer.setApp(new App("apply-system", "2.0.0")); deployer.showApp(); System.out.println("4. 启动新应用"); deployer.startApp(); System.out.println("5. 有异常,暂停新应用"); deployer.stopApp(); System.out.println("6. 回滚旧应用,拷贝备份的旧应用到服务器"); deployer.setAppBackup(space.getAppBackup()); deployer.showApp(); System.out.println("7. 启动备份的旧应用"); deployer.startApp(); } } 打印结果: 1. 暂停旧应用 暂停应用:App{content='apply-system', version='1.0.0'} 2. 备份旧应用 3. 拷贝新应用到服务器 App{content='apply-system', version='2.0.0'} 4. 启动新应用 启动应用:App{content='apply-system', version='2.0.0'} 5. 有异常,暂停新应用 暂停应用:App{content='apply-system', version='2.0.0'} 6. 回滚旧应用,拷贝备份的旧应用到服务器 App{content='apply-system', version='1.0.0'} 7. 启动备份的旧应用 启动应用:App{content='apply-system', version='1.0.0'}
备忘录模式代码实现搞定。有同窗会不会以为挺麻烦的,为何要有AppBackup
?咱们看看我的介绍,在对象以外保存状态,AppBackup 就是对象以外的对象,用来保存旧应用。
备忘录模式定义了一个备份机制。在不少场景都有相似备忘录模式的实现,好比数据库的事务的回滚机制。在日常业务开发中并无常用这个设计模式,可是咱们有使用它的思想,好比咱们用数据库或者其余中间件作备份数据,其中备份思想是一致的。
推荐阅读
设计模式系列文章持续更新中,欢迎关注公众号,一块儿交流学习。