设计模式:享元模式

十. 享元模式
整理自 《java与模式》阎宏编著


1.意图:
运用共享技术有效地支持大量细粒度的对象。

2.类图:
单纯享元模式:



复合享元模式:



3.原理:
享元对象能做到共享的关键是区分内蕴状态(Internal State)和外蕴状态(External State)。
一个内蕴状态是存储在享元对象内部的,并且不会随环境改变而有所不同的。因此,一个享元可以具有内蕴状态并可以共享。
一个外蕴状态是随环境改变而改变的,不可以共享状态。享元对象的外蕴状态必须由客户端保存,并在享元对象被创建之后,在需要使用的时候再传到享元对象内部。
外蕴状态不可以影响享元对象的内蕴状态,它们是相互独立的。所有的内蕴状态在对象创建完后就不可再改变。


4.特征:

单纯享元模式:
抽象享元角色:所有的具体享元类的超类,规定出需要实现的公共接口。那些需要外蕴状态的操作可以通过方法的参数传入。
具体享元角色:实现抽象享元角色所规定的接口。如果有内蕴状态的话,必须负责为内蕴状态提供存储空间。享元对象的内蕴状态必须与对象所处的周围环境无关,从而使得享元对象可以在系统内共享。
享元工厂角:负责创建和管理享元角色。本角色必须保证享元对象可以被系统适当地共享。当一个客户端对象调用一个享元对象时,享元工厂角色会检查系统中是否已经有一个符合要求的享元对象。如果有,享元工厂就提供这个已经有的享元对象,如果没有,享元工厂创建一个适当的享元对象。
客户端角色:需要维护一个对所有享元对象的引用。本角色需要自行存储所有享元对象的外蕴状态。

复合享元模式:
抽象享元角色:所有的具体享元类的超类,规定出需要实现的公共接口。那些需要外蕴状态的操作可以通过方法的参数传入。抽象享元的接口使得享元变得可能,但是并不强制子类实行共享,因此并非所有的享元对象都是可以共享的。
具体享元角色:实现抽象享元角色所规定的接口。如果有内蕴状态的话,必须负责为内蕴状态提供存储空间。享元对象的内蕴状态必须与对象所处的周围环境无关,从而使得享元对象可以在系统内共享。复合享元角色是由具体享元角色通过复合而成。
复合享元角色:复合享元角色所代表的对象是不可以共享的,但是可以分解成多个可以共享的具体享元角色。
享元工厂角:负责创建和管理享元角色。本角色必须保证享元对象可以被系统适当地共享。当一个客户端对象调用一个享元对象时,享元工厂角色会检查系统中是否已经有一个符合要求的享元对象。如果有,享元工厂就提供这个已经有的享元对象,如果没有,享元工厂创建一个适当的享元对象。
客户端角色:需要维护一个对所有享元对象的引用。本角色需要自行存储所有享元对象的外蕴状态。


5.说明:
6.使用案例:
Java中的String对象。
在编辑器系统中,每个字母做成一个享元对象,内蕴状态就是这个字母,而字母在文本中的位置和风格就是外蕴状态。

7.代码:
单纯享元模式:

// Client.java

public class Client

{

private FlyweightFactory flyweightFactory = null;

public Client()

{

flyweightFactory = new FlyweightFactory();

}

}

// FlyweightFactory.java
public class FlyweightFactory

{

private flyweight.Flyweight lnkFlyweight;

private HashMap flyweightPools;


public FlyweightFactory()

{

flyweightPools = new HashMap();

}


//客户端不能直接实例化享元类,必须通过工厂类。

public Flyweight getFlyweight(Object key)

{

if (flyweightPools.containsKey(key))

{

return (Flyweight) flyweightPools.get(key);

}

else

{

Flyweight newFlyweight = new ConcreteFlyweight(key);

flyweightPools.put(key, newFlyweight);

return newFlyweight;

}

}

}

// Flyweight.java

public interface Flyweight

{

//一个示意性的方法,参数是外蕴状态

void sampleOperation(Object extrinsicState);

}

// ConcreteFlyweight.java

public class ConcreteFlyweight implements Flyweight

{

private Object intrisnicState;



//构造函数,内蕴状态作为参数传入,

public ConcreteFlyweight(Object intrisnicState)

{

// initialize internal state

this.intrisnicState = intrisnicState;

}


//外蕴状态作为参数传入,修改了方法的行为,不改变内蕴状态。

public void sampleOperation(Object extrinsicState)

{

//....

}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值