享元模式

一、定义

享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。由于享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻量级模式,它是一种对象结构型模式。

二、享元模式结构图

享元模式中的角色:

1、Flyweight (享元抽象类):一般是接口或者抽象类,定义了享元类的公共方法。这些方法可以分享内部状态的数据,也可以调用这些方法修改外部状态。

2、ConcreteFlyweight(具体享元类):具体享元类实现了抽象享元类的方法,为享元对象开辟了内存空间来保存享元对象的内部数据,同时可以通过和单例模式结合只创建一个享元对象。

3、UnshareConcreteFlyweight(非共具体享元类):并不是所有的享元类都需要被共享的有的享元类就不要被共享,可以通过享元类来实例一个非共享享元对象。

4、Flyweight(享元工厂类):享元工厂类创建并且管理享元类,享元工厂类针对享元类来进行编程,通过提供一个享元池来进行享元对象的管理。一般享元池设计成键值对,或者其他的存储结构来存储。当客户端进行享元对象的请求时,如果享元池中有对应的享元对象则直接返回对应的对象,否则工厂类创建对应的享元对象并保存到享元池

三、示例

IgoChessman (抽象享元类)将公共方法给抽象

package flyweightPattern;
/**
 * 
* <p>Title: IgoChessman</p>  
* <p>Description: 围棋享元抽象类</p>  
* @author HAND_WEILI  
* @date 2018年9月12日
 */
 
public abstract  class IgoChessman {
	//共享抽象方法棋子的颜色
	public abstract String chessColor();
	
	public void display() {
		System.out.println("棋子:"+this.chessColor());
	}
}

 WhiteChessman :白棋类,实现具体的方法.

package flyweightPattern;
 
public class WhiteChessman extends IgoChessman {
 
	@Override
	public String chessColor() {
		// TODO Auto-generated method stub
		return "白色";
	}
 
}

BlackChessman :黑棋类,实现公共方法.

package flyweightPattern;
 
public class BlackChessman extends IgoChessman {
 
	@Override
	public String chessColor() {
		// TODO Auto-generated method stub
		return "黑色";
	}
 
}

IgoChessmanFactory :工厂类,使用的是单例模式创建,将享元对象唯一化。 

package flyweightPattern;
/**
 * 
* <p>Title: IgoChessmanFactory</p>  
* <p>Description:用单例模式来做这个工厂只提供一个对象 </p>  
* @author HAND_WEILI  
* @date 2018年9月12日
 */
 
import java.util.HashMap;
import java.util.Hashtable;
 
public class IgoChessmanFactory {
	//首先私有化自己的类
	private static IgoChessmanFactory igoChessmanFactory = new IgoChessmanFactory();
	//创建享元池
	private static  HashMap<String,IgoChessman > ht;
	
	//私有化构造函数自己创建自己 。
	private  IgoChessmanFactory() {
		//创建对应的棋子放进去.
		ht= new HashMap<String,IgoChessman >();
		IgoChessman white,black;
		white = new WhiteChessman();
		ht.put("白",white);
		black = new BlackChessman();
		//放入HASHTABLE
		ht.put("黑",black);
	   
	}
	
	//提供一个全局访问的方法。
	/**
	 * 
	 * <p>Title: getIgoChessmanFactory</p>  
	 * <p>Description: </p>  
	 * @return IgoChessmanFactory
	 */
	public static IgoChessmanFactory getIgoChessmanFactory() {
		return igoChessmanFactory;
	}
	
	//工厂方法创建对象 》
	public  static IgoChessman getIgoChessman(String name) {
		
		return(IgoChessman)ht.get(name);
		
	}
 
}

Clinet:客户端测试类。

package flyweightPattern;
 
public class Client {
	public static void main(String[] args) {
		IgoChessman b1,b2,w1,w2;
		IgoChessmanFactory igoChessmanFactory;
		//获取对应的工厂对象 
		igoChessmanFactory = IgoChessmanFactory.getIgoChessmanFactory();
		//判断是不是同一个对象。就是看是不是共享了。
		System.out.println(igoChessmanFactory);
		b1 = IgoChessmanFactory.getIgoChessman("黑");
		b2= IgoChessmanFactory.getIgoChessman("黑");
		System.out.println(b1==b2);
		w1 =IgoChessmanFactory.getIgoChessman("白");
		w2 =IgoChessmanFactory.getIgoChessman("白");
		System.out.println(w1==w2);
		b1.display();
		w1.display();
		w2.display();
		b2.display();
		
	}
}

四、享元模式优缺点

 

优点:

  1. 节约系统的开销。保证一个常用的对象只有一个!
  2. 外部状态不会影响内部状态,可以在不同环境下进行共享哦。

缺点:

  1. 享元模式使逻辑变得更加复杂,需要将享元对象分出内部状态和外部状态。
  2. 并且为了使对象可以共享,外部状态在很多情况下是必须有的,比如围棋的位置。当读取外部状态时明显会增加运行时间。

使用场景:

  • 一个系统有大量细粒度化的对象,占据大量的内存。
  • 对象大部分属性可以外部化,并且能将外部的属性放入内部属性中来。
  • 使用享元模式需要维护享元池,所以要用那种常用的经常调用的对象可以使用享元模式。

 五、享元模式总结

1、享元模式可以极大地减少系统中对象的数量。但是它可能会引起系统的逻辑更加复杂化。

2、享元模式的核心在于享元工厂,它主要用来确保合理地共享享元对象。

3、内部状态为不变共享部分,存储于享元享元对象内部,而外部状态是可变部分,它应当油客户端来负责

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值