文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
1.8 享元模式
利用 享元模式(Flyweight Pattern) 能够极大减少内存需求,因为它可以避免在处理包含很多极其相似部分的系统时,大量地去创建重量级对象。例如,利用一个复杂的字符类来构建文档,该字符类要处理 unicode、字体以及定位等情况。文档越大,如果文档中的每一个实际字符都需要一个特有的字符类实例的话,内存需求显然就会越大。相反,由于字符本身可能保存在字符串中,我们可能仅仅会用到单个的了解字符处理规范的字符类(或少量的字符类,比如一个字符类对应一个字体类型)。
在这种情境下,我们把这种由多个事物(比如字符类型)所共享的状态定义为 内部 (instrinsic)状态。它被重量级类所捕获。区分实际字符(可能只是它的 ASCII 码或 Unicode)的状态被称为 外部 (extrinsic)状态。
1.8.1 范例
首先我们构建一些较为复杂的飞机(第一种飞机与第二种存在一定的竞争关系,但有这一点与范例毫无关系):
class Boeing797 {
def wingspan = '80.8 m'
def capacity = 1000
def speed = '1046 km/h'
def range = '14400 km'
// ...
}
class Airbus380 {
def wingspan = '79.8 m'
def capacity = 555
def speed = '912 km/h'
def range = '10370 km'
// ...
}
如果想打造自己的机队,我们首先可能会去使用这些重量级类的很多实例。但在实际情况下,各架飞机可能只有很小的状态(外部状态)改动,所以我们还是借助重量级对象的单例,分别捕获外部状态即可(购买日期与资产编号,具体可参见下面的代码):
class FlyweightFactory {
static instances = [797: new Boeing797(), 380: new Airbus380()]
}
class Aircraft {
private type // 内部状态
private assetNumber // 外部状态
private bought // 外部状态
Aircraft(typeCode, assetNumber, bought) {
type = FlyweightFactory.instances[typeCode]
this.assetNumber = assetNumber
this.bought = bought
}
def describe() {
println """
Asset Number: $assetNumber
Capacity: $type.capacity people
Speed: $type.speed
Range: $type.range
Bought: $bought
"""
}
}
def fleet = [
new Aircraft(380, 1001, '10-May-2007'),
new Aircraft(380, 1002, '10-Nov-2007'),
new Aircraft(797, 1003, '10-May-2008'),
new Aircraft(797, 1004, '10-Nov-2008')
]
fleet.each { p -> p.describe() }
所以,按照这种方法,假如机队有几百家飞机的话,我们完全可以让一个重量级对象来对应一种类型的飞机。
但为了更进一步的高效率诉求,我们不再预先创建初始映射,而可能只延迟使用享元对象。
上面脚本运行结果为:
Asset Number: 1001
Capacity: 555 people
Speed: 912 km/h
Range: 10370 km
Bought: 10-May-2007
Asset Number: 1002
Capacity: 555 people
Speed: 912 km/h
Range: 10370 km
Bought: 10-Nov-2007
Asset Number: 1003
Capacity: 1000 people
Speed: 1046 km/h
Range: 14400 km
Bought: 10-May-2008
Asset Number: 1004
Capacity: 1000 people
Speed: 1046 km/h
Range: 14400 km
Bought: 10-Nov-2008
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论