聊聊Swift中的设计模式---行为型(备忘录模式)

197 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第27天,点击查看活动详情


前言

在面向对象的开发过程中,其实咱们或多或少的都接触过一些设计模式,可能知道或不知道其对应的名称,也不知道其具体使用场景,今天咱们就来说说几种常见的设计模式,帮助你们在开发过程中,更加得心应手。

正文

备忘录模式

备忘录模式,顾名思义就是在不破坏对象的前提下,通过命令给这个对象的进行拷贝,放在该对象之外的地方,方便遇到突发状况需要回撤或修改。

截屏2022-06-16 上午11.27.07.png

要完成一个备忘录模式 需要以下几个结构

  • 发起人:记录当前时刻的内部状态,负责定义哪些属于备份范围的状态,负责创建和恢复备忘录数据。
  • 备忘录:负责存储发起人对象的内部状态,在需要的时候提供发起人需要的内部状态。
  • 管理角色:对备忘录进行管理,保存和提供备忘录。

下面,咱们来通过一个例子说明一下

首先定义一个 文章类(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) 不能确保备忘录中的状态不被修改。

扩展阅读 下面还有其他模式

创建型-工厂模式

创建型-建造者模式

结构型-适配器模式

结构型-桥接模式

结构型-组合模式

结构型-装饰器模式

结构型-外观模式