设计模式(11)-结构型模式-Flyweight模式

本文介绍了享元模式的基本概念,包括其功能、结构及Java实现示例。享元模式通过区分对象的内部状态与外部状态来减少内存占用,适用于大量相似对象的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2.6     FLYWEIGHT

2.6.1 功能

                看到Flyweight想起来线程叫做lightweight进程:

                Lightweight:a fighter who is in a class of boxers weighing from 125 to 132 pounds (57 to 60kilograms)

                Flyweight:a fighter in a class of boxers who dos not weigh more than 112 pounds (51kilograms)

                看这个词知道这个对象是多么的轻量级,可是单个屌丝是弱小的,由屌丝组成的人民群众是很强大的。因此Flyweight要解决的问题是:假如这种对象多如牛毛,那么尝试将对象的状态分为内部状态和外部状态,如果内部数量和外部数量都很少,那么就皆大欢喜,这些外部状态有单独的对象去管理,而剩下的内部状态的对象以共享方式存在(即相同的内部状态只需要一个对象).这个过程就如同:本来是一个笛卡尔积,现在拆成两列存储,那么总数量将急剧减少。所以这种实现是以计算能力换内存空间的做法。

2.6.2结构


一旦一个类会出现不同的对象且对象间有一定的区别,就得瞄一瞄对象图了:


参与者:

•  F l y w e i g h t

                — 描述一个接口,通过这个接口f l y w e i g h t可以接受并作用于外部状态。

•  C o n c r e t e F l y w e i g h t

                — 实 现F l y w e i g h t 接 口 , 并 为 内 部 状 态 ( 如 果 有 的 话 ) 增 加 存 储 空 间 。Co n c r e t e F l y w e i g h t对象必须是可共享的。它所存储的状态必须是内部的;即,它必须独立于C o nc r e t e F l y w e i g h t对象的场景。

•  U n s h a r e d C o n c r e t e F l y w e i gh t

                — 并非所有的F l y w e i g h t子类都需要被共享。F l y w e i g h t接口使共享成为可能,但它并不强制共享。在F l y w e i g h t对象结构的某些层次,U n s h a r e d C o n c r e t e F l y w e i g h t对象通常将C o n c r e t e F l y w ei g h t对象作为子节点(R o w和Co l u m n就是这样) 。

•  F l y w e i g h t F a c t o r y

                — 创建并管理f l y w e i g h t对象。

                — 确保合理地共享f l y w e i g h t。当用户请求一个f l y w e i g h t 时,Fl y w e i g h t F a c t o r y对象提供一个已创建的实例或者创建一个(如果不存在的话) 。

•  Client

                — 维持一个对f l y w e i g h t的引用。

                — 计算或存储一个(多个) f l y w e i g h t的外部状态

协作:

•f l y w e i g h t执行时所需的状态必定是内部的或外部的。内部状态存储于C o n c r e t e F l y w e i g h t对象之中;而外部对象则由 C l i e n t对象存储或计算。当用户调用 f l y w e i g h t对象的操作时,将该状态传递给它

• 用户不应直接对C o n c r e t e F l y w e i g h t类进行实例化,而只能从 F l y w e i g h t F a c to r y对象得到Co n c r e t e F l y w e i g h t对象,这可以保证对它们适当地进行共享。

2.6.3 Java例子

下面的例子转自网上,表示了Flyweight模式的核心:

package DesignPattern;

 

/**

 *************************************

 * @Title   Flyweight.java

 * @Author 张作强

 * @Date    2010-8-21

 * @Comment抽象享元(Flyweight)角色

 *             此角色是所有的具体享元类的超类,

 *             为这些类规定出需要实现的公共接口。

 *             那些需要外蕴状态(External State)的操作可以通过调用商业方法以参数形式传入。

 *************************************

 */

public abstract class Flyweight {

 

       public abstract void Operation(int extrinsicState);

}

 

 

package DesignPattern;

 

/**

 *************************************

 * @Title   ConcreteFlyweight.java

 * @Author 张作强

 * @Date    2010-8-21

 * @Comment具体享元(ConcreteFlyweight)角色

 *             实现抽象享元角色所规定的接口。

 *             如果有内蕴状态的话,必须负责为内蕴状态提供存储空间。

 *             享元对象的内蕴状态必须与对象所处的周围环境无关,

 *             从而使得享元对象可以在系统内共享的。

 *************************************

 */

public class ConcreteFlyweight extends Flyweight {

 

       private String intrinsicState = "A";

      

       @Override

       public void Operation(int extrinsicState) {

              System.out.println("ConcreteFlyweight:intrinsicstate : " +intrinsicState + " , extrinsicstate : " + extrinsicState);

       }

}

 

package DesignPattern;

 

import java.util.Hashtable;

/**

 *************************************

 * @Title   FlyweightFactory.java

 * @Author 张作强

 * @Date    2010-8-21

 * @Comment享元工厂(FlyweightFactory)角色

 *              本角色负责创建和管理享元角色。

 *              本角色必须保证享元对象可以被系统适当地共享。

 *              当一个客户端对象调用一个享元对象的时候,

 *              享元工厂角色会检查系统中是否已经有一个符合要求的享元对象。

 *              如果已经有了,享元工厂角色就应当提供这个已有的享元对象;

 *              如果系统中没有一个适当的享元对象的话,享元工厂角色就应当创建一个合适的享元对象。

 *************************************

 */

public class FlyWeightFactory {

      

       private Hashtable<String,Flyweight>flyweights = new Hashtable<String, Flyweight>();

 

       public void addFlyweight(Strings , Flyweight f) {

              flyweights.put(s, f);

       }

 

       public FlyweightgetFlyweight(String key){

              Flyweightflyweight = (Flyweight)flyweights.get(key);

              if(flyweight ==null){

                     flyweight= new ConcreteFlyweight();

                     flyweights.put(key, flyweight);

              }

              return flyweight;

       }

      

       public intgetFlyweightFactorySize(){

              return flyweights.size();

       }

}

 

 

package DesignPattern;

 

/**

 *************************************

 * @Title   Client.java

 * @Author 张作强

 * @Date    2010-8-21

 * @Comment客户端(Client)角色

 *             本角色需要维护一个对所有享元对象的引用。

 *             本角色需要自行存储所有享元对象的外蕴状态。

 *************************************

 */

public class Client {

       public static void main(String[] args){

              int extrinsicState = 22;

              FlyWeightFactoryf = new FlyWeightFactory();

             

              f.addFlyweight("X", newConcreteFlyweight());

              f.addFlyweight("Y", newConcreteFlyweight());

//            f.addFlyweight("Z",new ConcreteFlyweight());

             

              Flyweightfx = f.getFlyweight("X");

              fx.Operation(extrinsicState);

             

              Flyweightfy = f.getFlyweight("Y");

              fy.Operation(extrinsicState);

             

//            当一个客户端对象调用一个享元对象的时候,

//            享元工厂角色会检查系统中是否已经有一个复合要求的享元对象。

//            如果已经有了,享元工厂角色就应当提供这个已有的享元对象;

//            如果系统中没有一个适当的享元对象的话,享元工厂角色就应当创建一个合适的享元对象。

              Flyweightfz = f.getFlyweight("Z");

              fz.Operation(extrinsicState);

             

              System.out.println("FlyweightFactorySize: "+ f.getFlyweightFactorySize());

       }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值