Option Pattern: 在不添加存储属性的前提下,提供了一种向已有类型中以类型安全的方式添加“存储”的手段。
使用步骤
- 为model定一个一个option接口 modelOption
protocol PersonOption { associatedtype Value static var defaultValue: Value { get } }
- 定义一个泛用的 options 字典,来将需要的选项值放到里面。加入 options 属性和下标方法
private var option: [ObjectIdentifier: Any] = [ObjectIdentifier: Any]() /// option的下标方法 subscript<T: PersonOption>(option type: T.Type) -> T.Value { get { option[ObjectIdentifier(type)] as? T.Value ?? T.defaultValue } set { option[ObjectIdentifier(type)] = newValue } }
- 为需要扩展的存储属性的类型,遵守modelOption
enum Color: PersonOption { case red case blue static var defaultValue: Color = .red } extension Int: PersonOption { static var defaultValue: Int = 0 }
- 在model的extension中拓展需要的'存储' 属性
extension Person { var color: Color { get { self[option: Color.self] } set { self[option: Color.self] = newValue } } var height: Int { get { self[option: Int.self] } set { self[option: Int.self] = newValue } } }
优点
- 节约内存开销
- 易于扩展,在extension中添加 ‘存储属性’,在不修改他人源码的情况下,为其扩展接口
demo
- 文中相关的代码可以在这里找到。
网友评论