持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第22天,点击查看活动详情
前言
在面向对象的开发过程中,其实咱们或多或少的都接触过一些设计模式,可能知道或不知道其对应的名称,也不知道其具体使用场景,今天咱们就来说说几种常见的设计模式,帮助你们在开发过程中,更加得心应手。
正文
享元模式
从字面意思上其实并不好理解,那咱们来用通俗的话说,享元模式就是共享内存地址。
打个比方,我有一个绿色的球,用了后就放在家里,有一天,我想要一个蓝色的球,忽然想起家里有个绿色的球没丢,我就回去拿,将绿色的盒子改成蓝色,那么我就有了一个蓝色的球。球还是那个球,只是外观变了。对应享元模式来说就是,对象的地址没变,只是对应的表现形式变了。
下面,咱们来通过一个例子来说一下。
首先还是先定义一个协议
import Foundation
protocol IFlyweight {
func setDetail(width: Int, height: Int)
}
复制代码
定义一个颜色类型
struct Color {
let type: String
init(type: String) {
self.type = type
}
}
复制代码
定义一个FlyweightImpl
类,遵守IFlyweight
协议,在这个类里面,除了定义width
和height
外,还增加一个Color
属性。然后定义一个方法,输出对象的地址和属性值
class FlyweightImpl: IFlyweight {
private var color: Color
private var width: Int
private var height: Int
init(color: Color) {
self.color = color
self.width = 0
self.height = 0
}
func setDetail(width: Int, height: Int) {
self.width = width
self.height = height
print("对象地址: (Unmanaged.passUnretained(self).toOpaque()) color: (color.type) width: (width) height: (height) ")
}
}
复制代码
接下来定义一个工厂方法,在这个工厂方法里面定义了一个私有字典,用于记录颜色字符串和颜色对应的指针。然后定义了一个getFlyweight
方法,返回传入颜色的地址。
扫描二维码关注公众号,回复:
14279321 查看本文章

class FlyweightFactory {
private var colorFlyweighMap: [String: FlyweightImpl] = [:]
func getFlyweight(colorName: String) -> FlyweightImpl? {
if colorFlyweighMap.keys.contains(colorName) {
return colorFlyweighMap[colorName]
} else {
let color = Color(type: colorName)
let impl = FlyweightImpl(color: color)
colorFlyweighMap[colorName] = impl
return impl
}
}
}
复制代码
最后咱们来看如何使用
let factory = FlyweightFactory()
let flyweight0 = factory.getFlyweight(colorName: "red")
flyweight0?.setDetail(width: 100, height: 200)
let flyweight1 = factory.getFlyweight(colorName: "red")
flyweight1?.setDetail(width: 100, height: 400)
let flyweight2 = factory.getFlyweight(colorName: "green")
flyweight2?.setDetail(width: 300, height: 300)
复制代码
输出的结果
对象地址: 0x0000600001824030 color: red width: 100 height: 200
对象地址: 0x0000600001824030 color: red width: 100 height: 400
对象地址: 0x0000600001812880 color: green width: 300 height: 300
复制代码
可以看到,定义为red
的颜色,虽然宽高不同,但是地址相同,体现了享元模式。
结语
优点:如果程序中有很多相似对象, 那么你将可以节省大量内存。
缺点:可能需要牺牲执行速度来换取内存, 因为他人每次调用享元方法时都需要重新计算部分情景数据。
总之,享元模式和tableview的复用有点相似,只不过享元模式要自己写,cell的复用苹果内部已经给我们做好了。
扩展阅读 下面还有其他模式