从FlyWeight
Gang of Four内的模式章节开始,FlyWeight模式适用于,当大多数对象状态可以是外在的时。
extrinsic state
是什么意思?我感觉这个模式用于共享对象。如果要共享对象,那么该对象如何甚至可以拥有任何状态?
答案 0 :(得分:8)
我们以一个Word处理器为例:
Word处理器处理Character对象。 Character对象的状态是字符内容,字体,样式,位置等(就Word处理器而言)。不同的文档使用不同的字符实例。假设我们只处理 a-z 字符,不同的文档使用 a-z 池中的字母,但可能会应用不同的字体/样式。因此,如果我们将字符的内容与字体/样式分开,我们可以共享这些字符,这是有道理的,因为与使用的字符的不同实例相比,总的不同类型的字符更少(在我们的情况下为26但在其他情况下为常量)在不同的文件中。共享这些字符实例意味着明智地共享Character实例内容,并在外部对这些字符应用字体/样式等上下文。字符内容是内在状态,字体/样式是外在状态。将状态分为内在和外在状态导致上述例子中的大量存储节省。
答案 1 :(得分:6)
extrinsic - 属于对象上下文(外部)或该实例唯一的状态
内在 - 自然属于'FlyWeight'对象的状态,因此应该是永久的或不可变的(内部的)或无上下文的。
答案 2 :(得分:3)
无论该项目符号列表中的具体措辞如何,理解该消息非常重要: Flyweight 适用于可以在许多对象之间共享重要数据部分的情况,因为它是不可变的。带有字体面的示例使这一点非常清楚;日常Java中的一个例子是java.util.regex.Pattern
,它是不可变外在状态的持有者,而Matcher
是重复使用它并保持局部内在状态的轻量级。许多Matcher
可以并行存在,所有都在内部重用已编译的正则表达式。
这句话使事情比你问题中的更明确:
共享的flyweights越多,存储空间就越大。随着共享状态的数量,节省增加。当对象使用大量的内在和外在状态时,可以实现最大的节省,并且可以计算外部状态而不是存储外部状态。然后以两种方式节省存储:共享降低了固有状态的成本,并且您将外部状态换成计算时间。
答案 3 :(得分:1)
Gang of Four’s Flyweight设计模式引入了本征状态和本征状态的概念:
此处的关键概念是内在状态与外在状态之间的区别。内在状态存储在举重装置中;它包含的信息与飞行重量的背景无关,因此可共享。外在状态取决于飞重的上下文并随其变化,因此无法共享。客户对象负责在需要时将外部状态传递给flyweight。
换句话说,相对于一组对象,对象的状态可以被分解为内在状态和外在状态,其中内在状态是交叉点。组中所有对象的状态和外部状态的em>是对象状态和固有状态的差异。由于本征状态在组的每个对象中都是重复的,因此可以通过用存储单个本征状态的单个 flyweight 对象替换该组对象来节省空间。然而,flyweight对象无法存储该组对象的多个外部状态,因此外部状态将存储在外部,并在来自客户端对象的每个请求中传递给flyweight对象。这种优化的通信协议通常被称为 stateless protocol ,因为蝇量对象不存储外部状态。无状态协议的示例包括IP和HTTP(更常见的是所有REST协议,其中固有状态称为资源状态,而外部状态称为应用程序状态)。
例如,让我们将三个对象与它们各自的客户端一起使用:
o1←c1
o2←c2
o3←c3
我们可以相对于三个对象分解每个对象的状态:
状态1 = 内部状态∪外部状态1
状态2 = 内部状态∪外部状态2
状态3 = 内部状态∪外部状态3其中:
本征状态 = 状态1 ∩状态2 ∩状态3
外部状态1 = 状态1 \ 内部状态
外部状态2 = 状态2 \ 内部状态
外部状态3 = 状态3 \ 内部状态
此处固有状态被复制。因此,将其存储在单个flyweight对象中(并将外部状态移动到客户端)可以节省空间:
o←c1,c2,c3