Swift 什么是Adapter和Memento模式
在这篇文章中,你将了解到Swift语言中的这两种模式。此外,你还会看到使用这些模式的优势是什么。你将看到如何在你的项目中采用这些模式的例子。
使用适配器模式,你可以设计一个系统,让两个不同的接口一起工作或在它们之间进行通信。你可以通过符合某种协议的类或结构来实现这种设计模式。然后,你可以使用该类或结构的实例来与符合不同协议的对象进行交互。
使用纪念品模式,你可以设计一个系统,允许一个对象恢复到以前的状态。你可以用可以存储对象状态的类或结构来实现这种设计模式。为了管理这些存储,你需要创建存储和恢复状态的方法。
这两种设计模式都是用来通过将对象相互解耦来使你的代码更加灵活和可重用。
Adapter模式
当有一个现有的类或结构提供特定的功能时,就会采用适配器模式。不过,你必须以一种与它的当前接口不兼容的方式来利用它。现有的类或结构和新的接口可以和谐地共存,这要感谢适配器类或结构,它是它们之间的桥梁。
想一想这样的情况:你已经有一个提供项目列表的类。然而,这个类并不打算用于iOS中的表视图。你可以开发一个符合UITableViewDataSource协议的适配器类,将该类用于表视图。为了给表格视图提供数据,这个适配器类依赖于现有的类。
例子
下面是一个Swift中的适配器模式的例子
protocol LegacyData {
func getData() -> [String]
}
class LegacyDataProvider: LegacyData {
func getData() -> [String] {
return ["item1", "item2", "item3"]
}
}
protocol NewData {
func getData() -> [String]
}
class NewDataAdapter: NewData {
private let legacyData: LegacyData
init(legacyData: LegacyData) {
self.legacyData = legacyData
}
func getData() -> [String] {
return legacyData.getData()
}
}
let legacyDataProvider = LegacyDataProvider()
let newDataAdapter = NewDataAdapter(legacyData: legacyDataProvider)
print(newDataAdapter.getData())
输出
["item1", "item2", "item3"]
在这里,LegacyDataProvider是一个现有的类,它以某种格式提供数据,但它与NewData协议所定义的新接口不兼容。NewDataAdapter类作为两者之间的桥梁,允许LegacyDataProvider与新接口一起使用。
使用适配器模式的一些优势包括
- 它允许整合不兼容的类
-
它允许接口和实现的分离
-
它允许重用现有的类
-
它允许轻松地添加新的类
Memento模式
当一个对象的状态需要被保存以便以后可以恢复时,Memento模式被采用。该对象的状态被存储在Memento类或结构中,它提供了生成、恢复和访问Memento的方法。
例如,考虑这样一种情况:你正在构建一个绘图应用程序,你想让用户撤销和重做他们的操作。你可以使用Memento模式来存储每一步的画布状态,这样用户就可以轻松地撤销和重做他们的操作。
例子
下面是Swift中Memento模式的一个例子
class DrawingCanvas {
private var shapes: [Shape] = []
func addShape(_ shape: Shape) {
shapes.append(shape)
}
func undo() -> [Shape] {
return Memento.undo(from: &shapes)
}
func redo() -> [Shape] {
return Memento.redo(from: &shapes)
}
func save() {
Memento.save(from: shapes)
}
private struct Memento {
private static var undoStack: [[Shape]] = []
private static var redoStack: [[Shape]] = []
static func undo(from shapes: inout [Shape]) -> [Shape] {
guard !undoStack.isEmpty else { return [] }
let currentState = undoStack.removeLast()
redoStack.append(shapes)
return currentState
}
static func redo(from shapes: inout [Shape]) -> [Shape] {
guard !redoStack.isEmpty else { return [] }
let currentState = redoStack.removeLast()
undoStack.append(shapes)
return currentState
}
static func save(from shapes: [Shape]) {
undoStack.append(shapes)
redoStack.removeAll()
}
}
struct Shape {
}
}
在这里,DrawingCanvas 类有一个私有的 memento 属性,它是 Memento 结构的一个实例。该属性负责在每个步骤中保存DrawingCanvas类的状态。DrawingCanvas有撤销和重做方法,使用Memento的撤销和重做方法来恢复画布的状态。
使用Memento模式的一些优点包括
- 它允许撤消和重做操作
-
它允许轻松保存和恢复一个对象的状态
-
它允许对象和其状态的解耦
-
它允许关注点的分离
总结
有两种设计模式可以帮助开发者解决软件开发中的典型问题,即Adapter和Memento模式。Memento模式使一个项目能够保存和恢复它以前的状态,而Adapter模式使具有不兼容接口的对象能够合作。这两种模式都鼓励松散耦合和关注点的分离,它们可以帮助你创建设计更有效的代码。了解何时应用这些模式以及如何在你的代码库中正确地应用这些模式是至关重要的。