设计模式(Java随笔)—享元模式

享元模式(Flyweight Pattern):池技术的重要实现方式,可以降低大量重复的,细粒度的类在内存中的开销

Use sharing to support large numbers of fine-grained objects efficiently.

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

掌握享元模式的关键在于区分内部状态和外部状态:

  • 内部状态:存储在享元对象内部的,可以共享的信息,不会随环境的改变而改变,可变性小
  • 外部状态:随环境改变而改变,不可共享,由客户端输入保存,在需要的时候再传入

享元模式的四种角色:

  • 抽象享元(Flyweight)角色:对享元类进行抽象,如果模式中有需要外部状态可以首先以参数的形式定义
  • 具体享元(Concrete Flyweight)角色:抽象享元角色的实现,在该类中定义内部状态,由于内部状态不随环境改变,故可定义内部状态为私有
  • 享元工厂(Flyweight Factory)角色:构造一个池容器,负责创建和管理享元角色,提供获得享元角色的静态方法,保证已存在的实例对象的唯一,常将工厂的构造方法定义为私有
  • 客户端(Clinet)角色:需要自行存储所有享元对象的外部状态

java基础类库中大量使用了享元模式,如String、Integer、Boolean、Character等类都通过享元模式提供了内部的池化机制

列:

String str1="hello java!";
String str2="hello java!";
System.out.println(str1.equals(str2));

//结果为 true

返回值为true,表示这两个字符串是相同的实例;

享元模式基础代码实现:

import java.util.HashMap;
import java.util.Map;

public class FlyweightModel {
	/*
	 * 享元模式
	 */
	public static void main(String[] args) {
		
		String intrinsicState="in";
		Flyweight flyweight=FlyweightFactory.getFlyweight(intrinsicState);
		flyweight.operation("ex");
	}
}

//抽象享元角色
interface Flyweight{
	void operation(String extrinsicState);//参数为外部状态
}

//具体享元角色
class ConcreteFlyweight implements Flyweight{
	private String intrinsicState;//内部状态
	public ConcreteFlyweight(String intrinsicState) {
		this.intrinsicState=intrinsicState;
	}
	@Override
	public void operation(String extrinsicState) {
		System.out.println("内部状态:"+intrinsicState+"\n"+"外部状态:"+extrinsicState);
	}
}

//享元工厂角色
class FlyweightFactory{
	private static Map<String, Flyweight> pool=new HashMap<String, Flyweight>();
	private FlyweightFactory() {};
	
	public static Flyweight getFlyweight(String intrinsicState) {
		Flyweight flyweight=pool.get(intrinsicState);
		if(flyweight==null) {
			flyweight=new ConcreteFlyweight(intrinsicState);
			pool.put(intrinsicState, flyweight);
		}
		return flyweight;
	}
}

运行结果:

内部状态:in
外部状态:ex

享元模式围棋落子实例:

——围棋和五子棋只有黑白两色,所以颜色应该是棋子的内部状态,而棋子之间的不同在于位置不同,所以方位坐标应该是棋子的外部状态,强调棋子对象减少到只有两个实例

public class FlyweightModel {
	/*
	 * 享元模式—围棋落子
	 */
	public static void main(String[] args) {
		String color="黑";
		int x=0;
		int y=0;
		WQFlyweight wqFlyweight;
		for(int i=0;i<5;i++) {
			x=(int)(19*Math.random());
			y=(int)(19*Math.random());
			wqFlyweight=WQFlyweightFactory.getWQFlyweight(color);
			if(color.equals("黑")) {
				color="白";
			}else {
				color="黑";
			}
			if(wqFlyweight!=null) {
				wqFlyweight.put(x, y);
			}
		}
	}
}
//享元模式实现围棋落子
//1、抽象享元类(外部状态(x,y))
interface WQFlyweight{
	void put(int x,int y);//外部状态,棋子位置
}

//2、具体享元类(内部状态(黑,白))
class WQConFlyweight implements WQFlyweight{
	private String color;
	public WQConFlyweight(String color) {
		this.color=color;
	}
	@Override
	public void put(int x, int y) {
		
		System.out.println(color+"子:落于"+"("+x+","+y+")"+"位置");
	}
}

//3、享元工厂类
class WQFlyweightFactory{
	//确保内部状态实例只有两个
	private static WQFlyweight WHITE;
	private static WQFlyweight BLACK;
	private WQFlyweightFactory() {};
	public static WQFlyweight getWQFlyweight(String color) {
		if(color.equals("白")) {
			if(WHITE==null) {
				 WHITE=new WQConFlyweight("白");
			}
			return WHITE; 
		}else if(color.equals("黑")) {
			if(BLACK==null) {
				BLACK=new WQConFlyweight("黑");
			}
			return BLACK; 
		}
		return null;
	}
}

运行结果:

黑子:落于(7,12)位置
白子:落于(9,10)位置
黑子:落于(4,10)位置
白子:落于(11,2)位置
黑子:落于(10,14)位置

参考书籍:

《大话设计模式》——程杰

《设计模式(Java版)》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值