持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第27天,点击查看活动详情
前言
在面向对象的开发过程中,其实咱们或多或少的都接触过一些设计模式,可能知道或不知道其对应的名称,也不知道其具体使用场景,今天咱们就来说说几种常见的设计模式,帮助你们在开发过程中,更加得心应手。
正文
备忘录模式
备忘录模式,顾名思义就是在不破坏对象的前提下,通过命令给这个对象的进行拷贝,放在该对象之外的地方,方便遇到突发状况需要回撤或修改。
要完成一个备忘录模式 需要以下几个结构
- 发起人:记录当前时刻的内部状态,负责定义哪些属于备份范围的状态,负责创建和恢复备忘录数据。
- 备忘录:负责存储发起人对象的内部状态,在需要的时候提供发起人需要的内部状态。
- 管理角色:对备忘录进行管理,保存和提供备忘录。
下面,咱们来通过一个例子说明一下
首先定义一个 文章类(Article)里面定义了一些属性和保存与撤销的方法。
(ps :这个类继承的CustomDebugStringConvertible是swift的标准库,实现的debugDescription 可以自定义输出Article的实例对象)
struct Article : CustomDebugStringConvertible{
var title: String
var content: String
var cover: String
func saveToMemento() -> ArticleMemento {
return ArticleMemento(article: self)
}
mutating func undoFromMemento(_ memento: ArticleMemento) {
self.title = memento.title
self.content = memento.content
self.cover = memento.cover
}
var debugDescription: String {
return "Article: (title) - (content) - (cover)"
}
}
然后在定义一个备忘录类ArticleMemento 同样继承自CustomDebugStringConvertible,可以自定义输出值
class ArticleMemento : CustomDebugStringConvertible {
var title: String
var content: String
var cover: String
init(article: Article) {
self.title = article.title
self.content = article.content
self.cover = article.cover
}
var debugDescription: String {
return "ArticleMemento: (title) - (content) - (cover)"
}
}
最后定义一个备忘录管理类(ArticleMementoManager),里面定义了一个数组,用来装备忘录。
然后增加了两个方法,getMemento():获取数组中最后一个、addMemento:将备忘录添加到数组中。
class ArticleMementoManager {
private var mementos = [ArticleMemento]()
func getMemento() -> ArticleMemento? {
return self.mementos.popLast()
}
func addMemento(_ memento: ArticleMemento) {
self.mementos.append(memento)
}
}
最后咱们来看如何使用的
let articleMememtoma = ArticleMementoManager()
var article = Article(title: "设计模式", content: "内容", cover: "https://test.png")
articleMememtoma.addMemento(article.saveToMemento())
print(article)
article.title = "设计模式A"
article.content = "内容A"
article.cover = "https://test.a.png"
articleMememtoma.addMemento(article.saveToMemento())
print(article)
article.title = "设计模式B"
article.content = "内容B"
article.cover = "https://test.b.png"
articleMememtoma.addMemento(article.saveToMemento())
print(article)
print("\n回退到上一步")
if let mememto = articleMememtoma.getMemento() {
article.undoFromMemento(mememto)
}
print(article)
print("\n回退到上一步")
if let mememto = articleMememtoma.getMemento() {
article.undoFromMemento(mememto)
}
print(article)
print("\n回退到上一步")
if let mememto = articleMememtoma.getMemento() {
article.undoFromMemento(mememto)
}
print(article)
输出结果
Article: 设计模式 - 内容 - https://test.png
Article: 设计模式A - 内容A - https://test.a.png
Article: 设计模式B - 内容B - https://test.b.png
回退到上一步
Article: 设计模式B - 内容B - https://test.b.png
回退到上一步
Article: 设计模式A - 内容A - https://test.a.png
回退到上一步
Article: 设计模式 - 内容 - https://test.png
结语
备忘录模式适合应用场景
- 当你需要创建对象状态快照来恢复其之前的状态时, 可以使用备忘录模式。
- 当直接访问对象的成员变量、 获取器或设置器将导致封装被突破时, 可以使用该模式。
备忘录模式优缺点
优点
- 你可以在不破坏对象封装情况的前提下创建对象状态快照。
- 方便用户回滚操作
缺点
- 如果客户端过于频繁地创建备忘录, 程序将消耗大量内存。
- 绝大部分动态编程语言 (例如 PHP、 Python 和 JavaScript) 不能确保备忘录中的状态不被修改。
扩展阅读 下面还有其他模式