通过共享技术有效地支持大量细粒度的对象。
Flyweight是一个共享对象,它可以同时在不同上下文(Context)使用,并在每个上下文中Flyweight都可以作为一个独立的对象。Flyweight关键概念是内部状态和外部状态的区别。内部状态存在Flyweight中,外部状态取决于Flyweight上下文,因此不能共享。
Flyweight模式对那些通常因为数量太大而难以用对象来表示的概念或实体进行建模。
<shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"></shapetype><stroke joinstyle="miter"></stroke><formulas></formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f><lock aspectratio="t" v:ext="edit"></lock><shape id="_x0000_i1025" style="WIDTH: 431.25pt; HEIGHT: 233.25pt" type="#_x0000_t75"></shape><imagedata o:title="" src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image001.png"></imagedata>
参与者:
Flyweight(character)
描述一个接口,通过这一个接口Flyweight可以接受并作用于外部状态。
ConcreteFlyweight(Character A,B,…)
实现Flyweight接口,并为内部状态增加存储空间,ConcreteFlyweig对象必须是共享的。它所存储的状态必须是内部的;即,它必须独立于ConcreteFlyweight对象上下文。
UnsharedConcreteFlyweight(not used)
并非所有的Flyweight字类都需要被共享。Flyweight接口使共享成为可能,但它并不强制共享。在Flyweight对象结构某些层次,UnsharedConcreteFlyweight对象通常将ConcreteFlyweight对象作为字节点。
FlyweightFactory(CharacterFactory)
创建并管理Flyweight对象。
确保合理的共享Flyweight。当用户请求一个Flyweight时,FlyweightFactory对象提供一个已经创建的实例或创建一个(如果不存在的话)。
Client(FlyweightApp)
维持一个对Flyweight的引用。
计算或存储一个(多个)Flyweight的外部状态。
代码:
import java.util.HashMap;
import java.util.Map;
/**
* FlyweightFactory
* @author tyrone
*/
public class CharacterFactory {
private Map characters=new HashMap();
public Character GetCharacter(char key){
Character character=(Character) characters.get(String.valueOf(key));
if (character==null ){
switch(key){
case 'A':character=new CharacterA(); break;
case 'B':character=new CharacterB(); break;
//...
case 'Z':character=new CharacterZ(); break;
}
characters.put(String.valueOf(key),character);
}
return character;
}
}
/**
* Flyweight
* @author tyrone
*/
public abstract class Character {
protected char symbol;
protected int width;
protected int height;
protected int ascent;
protected int descent;
protected int pointSize;
//methods
public abstract void Draw(int pointSize);
}
/**
* ConcreteFlyweight
* @author tyrone
*
*/
public class CharacterA extends Character {
public CharacterA(){
this.symbol='A';
this.height=100;
this.width=120;
this.ascent=70;
this.descent=0;
}
/* (非 Javadoc)
* @see Character#Draw(int)
*
*/
public void Draw(int pointSize) {
this.pointSize=pointSize;
System.out.println(this.symbol);
}
}
/**
* @author tyrone
*/
public class CharacterB extends Character {
public CharacterB(){
this.symbol='B';
this.height=100;
this.width=140;
this.ascent=72;
this.descent=0;
}
/* (非 Javadoc)
* @see Character#Draw(int)
*
*/
public void Draw(int pointSize) {
this.pointSize=pointSize;
System.out.println(this.symbol);
}
}
/**
* @author tyrone
*
*/
public class CharacterZ extends Character {
public CharacterZ(){
this.symbol='Z';
this.height=100;
this.width=100;
this.ascent=68;
this.descent=0;
}
/* (非 Javadoc)
* @see Character#Draw(int)
*
*/
public void Draw(int pointSize) {
this.pointSize=pointSize;
System.out.println(this.symbol);
}
}
/**
* FlyweightApp test
* @author tyrone
*
*/
public class FlyweightApp {
public static void main(String[] args) {
String document="ABZZAA";
CharacterFactory f=new CharacterFactory();
int pointSize=12;
for(int i=0;i<document.length();i++){
Character character=f.GetCharacter(document.charAt(i));
character.Draw(pointSize);
}
}
}
结果
ABZZAA