原版设计模式之享元模式(Flyweight)

Intent (定义)

Use sharing to support large numbers of fine-grained objects efficiently(使用共享可以有效地支持大量的细粒度对象。

Motivation (详细说明)

如下图所示,这是一个文档编辑器,有字符对象,列对象和行对象。
每次在文档中书写单词时,都需要一个字符对象和列对象,换行则需要一个行对象。
当文档内容比较多时,则需要大量的内存来保存对象。
在这里插入图片描述
A flyweight is a shared object that can be used in multiple contexts simultaneously.(享元对象是一个共享对象,可以在多个上下文中同时使用
The flyweight acts as an independent object in each context—it’s indistinguishable from an instance of the object that’s not shared.(享元对象和未共享对象的实例难以区分,因此享元对象在上下文中可以作为一个独立的对象存在。
Flyweights cannot make assumptions about the context in which they operate. The key concept here is the distinction between intrinsic and extrinsic state.(享元对象不能区分运行环境上下文,区分的关键在于内在状态和外在状态之间的差别
Intrinsic state is stored in the flyweight; it consists of information that’s independent of the flyweight’s context, thereby making it sharable.(内在状态存储在享元对象中,它不依赖于享元对象的上下文,因此是可共享的
Extrinsic state depends on and varies with the flyweight’s
context and therefore can’t be shared.(外在状态依赖享元对象的上下文,因此不能共享
Client objects are responsible for passing extrinsic state to the flyweight when it needs it.(客户端使用享元对象时,需要将外在状态传递给它。

如下图,不使用享元模式时的对象图,
在这里插入图片描述
下图是使用享元模式的对象图,
在这里插入图片描述
A flyweight representing the letter “a” only stores the corresponding character code; it doesn’t need to store its location or font. Clients supply the context-dependent information that the flyweight needs to draw itself.(表示字母A的享元对象只需要存储A字符编码,不需要存储位置和字体。客户端给享元对象提供上下文信息,让他们可以绘制字母A在指定位置。

在这里插入图片描述
参考代码

Applicability (适用点)

The Flyweight pattern’s effectiveness depends heavily on how and where it’s used. (享元模式发挥作用很大程度上依赖上下文和使用方式
Apply the Flyweight pattern when all of the following are true:(当如下条件都满足时可以使用享元模式

  • An application uses a large number of objects.(应用程序使用了大量对象
  • Storage costs are high because of the sheer quantity of objects.(对象很多导致耗费存储空间
  • Most object state can be made extrinsic. (大多数对象的状态可以是外部传递
  • Many groups of objects may be replaced by relatively few shared objects once extrinsic state is removed.(外部状态被移除后,许多组对象可以被少量的共享对象取代。
  • The application doesn’t depend on object identity. Since flyweight objects may be shared, identity tests will return true for conceptually distinct objects.(应用程序不依赖于对象标识。由于享元对象是共享的,对于概念上不同的对象,其对象标识测试将返回true.

Structure (结构)

在这里插入图片描述
下图展示了享元对象是如何被共享的:
在这里插入图片描述

Participants (参与者)

  • Flyweight (享元对象
    • declares an interface through which flyweights can receive and act on extrinsic state.(声明一个可以接受并按照外部状态运作的接口
  • ConcreteFlyweight (Character) (具体的享元对象
    • implements the Flyweight interface and adds storage for intrinsic state, if any. A ConcreteFlyweight object must be sharable. Any state it stores must be intrinsic; that is, it must be independent of the ConcreteFlyweight object’s context.(实现Flyweight接口,当有内部状态时,需要存储内部状态。具体的享元对象必须是可共享的。任何它存储的状态都应该是内部状态。也就是说,应该是独立于具体享元对象的上下文。
  • UnsharedConcreteFlyweight (Row, Column)(不可共享的享元对象
    • not all Flyweight subclasses need to be shared. The Flyweight interface enables sharing; it doesn’t enforce it. It’s common for UnsharedConcreteFlyweight objects to have ConcreteFlyweight objects as children at some level in the flyweight object structure (as the Row and Column classes have). (并不是所有的Flyweight子类都需要共享。Flyweight接口支持共享,但不是强制的。对于不需要共享的享元对象,在享元结构中通常会被聚合使用(例如Row,Column类)。
  • FlyweightFactory (享元工厂
    • creates and manages flyweight objects. (创建并管理享元对象
    • ensures that flyweights are shared properly. When a client requests a flyweight, the FlyweightFactory object supplies an existing instance or creates one, if none exists.(确保享元对象被正确的共享。当客户端请求享元对象,享元工厂提供已存在的享元实例,当不存在实例则新建一个返回。
  • Client (客户端
    • maintains a reference to flyweight(s). (引用享元对象
    • computes or stores the extrinsic state of flyweight(s).(计算或存储享元对象的外部状态

Collaborations (约定)

  • State that a flyweight needs to function must be characterized as either intrinsic or extrinsic. Intrinsic state is stored in the ConcreteFlyweight object; extrinsic state is stored or computed by Client objects. Clients pass this state to the flyweight when they invoke its operations.(享元对象的状态要起作用必须变成内在的或外在的。内在状态存储在ConcreteFlyweight中;外部状态由客户端存储或计算。客户端在调用时将此状态传递给享元对象。
  • Clients should not instantiate ConcreteFlyweights directly. Clients must obtain ConcreteFlyweight objects exclusively from the FlyweightFactory object to ensure they are shared properly.(客户端不能直接实例化ConcreteFlyweight对象。客户端必须从FlyweightFactory获取享元对象,以保证被正确的共享。

Related Patterns (相关模式)

  • The Flyweight pattern is often combined with the Composite (183) pattern to implement a logically hierarchical structure in terms of a directed-acyclic graph with shared leaf nodes.(享元模式通常和组合模式结合使用,以形成图结构
  • It’s often best to implement State (338) and Strategy (349) objects as flyweights.(通常最好作为享元对象的是状态对象和策略对象
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值