结构型--享元模式

概念


 运用共享技术有效地支持大量细粒度的对象。
 享元模式的主要目的是实现对象的共享,即共享池,当系统中对象多的时候用这个模式可以减少内存的开销,避免内存溢出,减少重复代码量,通常与工厂模式一起使用。该模式用来减少需要创建的对象的数量(共享池中有一样的就直接返回),以减少内存占用和提高性能。
 系统中有大量对象,每个对象的状态/成员大部分是外部状态,如果去掉外部状态,就可以用很少的共享对象来代替原系统对象,则把共享部分放在共享池中;创建对象时,享元模式尝试重用共享池中已有的对象,如果未找到匹配的对象,才会去创建新的对象。之后,外部状态作为对象方法的参数来为对象配置外部环境。

优点:

  1. 大大减少对象的创建,降低系统的内存,使效率提高。

缺点:

  1. 提高了系统的复杂度,需要分离出外部状态和内部状态,内部状态存储于享元中,不随外部场景而变,外部状态取决于场景,随场景而变化。
     

举例


package flyweight ;

import java.util.Vector;
public class User {
	public static void main(String[] args) {
		FlyweightFactory flyweightFactory = new FlyweightFactory();
		Glyph glyph = null;
		CharacterContext characterContext = null;
		for(int i = 0; i < 5; i++) {
			glyph = flyweightFactory.CreateCharacter((char)(i+97));
			characterContext = new CharacterContext(
					ProduceContext.getRandomNumber(),
					ProduceContext.getRandomNumber(),
					ProduceContext.getRandomColor());
			glyph.draw(characterContext);
	     }
    }
}

//产生状态信息的类(与模式无关)
class ProduceContext{
	private static final String colors[] = { "Red", "Green", "Blue", "White", "Black" };
	public static String getRandomColor() {
	     return colors[(int)(Math.random()*colors.length)];
	}
	public static int getRandomNumber() {
		 return (int)(Math.random()*100 );
	}
}

//Character的外部状态信息类
class CharacterContext {
	protected String color;
	protected int x;
	protected int y;
	public CharacterContext() { }
	public CharacterContext(int x, int y, String color) {
		this.x = x;
		this.y = y;
		this.color = color; 
	}
	public int getX() {
		return x;
	}
	public int getY() {
		return y;
	}
	public String getColor() {
		return color;
	}
}

//Flyweight接口,实现类可以是可共享对象也可以是不可共享对象
interface Glyph { 
	void draw(CharacterContext circleContext);
}

/*该可共享类在每一个场景中都可作为一个独立的对象
因为,尽管对象一样,但对象调用方法时所处的环境是不同的
ConcreteFlyweight类,Flyweight的实现类
*/
class Character_1 implements Glyph {
	private char c;//内部状态信息,被共享的量
	public Character_1(char c) {
		this.c = c;
	}
	public char getChar() {
		return c;
	}
	public void draw(CharacterContext circleContext) {
		 System.out.println("Character: Draw() [Color : " + circleContext.getColor()
				 +", x : " + circleContext.getX() +", y :" + circleContext.getY()
				 +", Character: "+ c+" ]");
	}
}

//UnsharedConcreteFlyweight类,Flyweight的实现类
class Row implements Glyph {
	public void draw(CharacterContext circleContext) {
		System.out.println("UnsharedConcreteFlyweight Row");
	}
}
class Column implements Glyph {
	public void draw(CharacterContext circleContext) {
		System.out.println("UnsharedConcreteFlyweight Column");
	}
}

//FlyweightFactory,用来创建flyweight对象
class FlyweightFactory {
	private static final Vector<Glyph> GlyphPool = new Vector<>(26);
	public FlyweightFactory() {
		for(char i = 'a'; i <= 'z'; i++) {
			GlyphPool.add(new Character_1(i));
		}
	}
	public Character_1 CreateCharacter(char c) {
		Character_1 character = null;
		int flag = 0;
		for(Glyph glyph : FlyweightFactory.GlyphPool) {
			Character_1 ch = (Character_1)glyph;
			if(ch.getChar() == c) {
				flag = 1;
				character = ch;
				break;
			}
		}
		if(flag == 0) {
			character = new Character_1(c);
			GlyphPool.add(character);
		}
		return character;
	}
	public Row CreateRow() {
		return new Row();
	}
	public Column CreateColumn() {
		return new Column();
	}
	//test,查看是否没有创建已有对象
	public static void showPool() {
		for(Glyph g : FlyweightFactory.GlyphPool) {
			Character_1 ch = (Character_1)g;
			System.out.println(ch.getChar());
		}
	}
}

Output:
Character: Draw() [Color : Green, x : 75, y :23, Character: a ]
Character: Draw() [Color : Blue, x : 59, y :66, Character: b ]
Character: Draw() [Color : Red, x : 26, y :92, Character: c ]
Character: Draw() [Color : Green, x : 10, y :90, Character: d ]
Character: Draw() [Color : Blue, x : 87, y :11, Character: e ]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值