享元模式,还是从名字引出定义吧,享,共享,元,基本的意思,合起来就是:大家共享基本的东西。
享元模式即为了节约系统资源,将系统中大量相同或相似的对象进行复用。也就是说如果大量对象相同,大家用这一个就行。
享元模式UML类图如图:
实例代码如下:
最近小黄车挺火,就以小黄车举例吧,话说某天小黄车为了吸引用户使用,又向市场上投放了小蓝车,小黄车和小蓝车架子相同,就是涂的颜色不同。同时,小黄车上带上了定位,系统为了检测小黄车小蓝车位置,必须要有他们的当前坐标。所以可以这样设计类:
设计一个抽象类,作为小车的父类,设计两个子类,分别代表小黄车小蓝车。为了说明小车位置,还有一个坐标类。这里还有个外部状态(小车位置)内部状态概念,写完示例代码再说明一下。
抽象享元类:
/****
* 抽象享元类(抽象自行车车类)
* @author wjw
*
*/
public abstract class AbstractBike {
public abstract String getColor();
public void where(Coordinate coordinate){
System.out.println(this.getColor() + "在(" + coordinate.getX() + "," + coordinate.getY() + ")位置处。");
}
}
小黄车类:
public class YellowBike extends AbstractBike{
@Override
public String getColor() {
// TODO Auto-generated method stub
return "小黄车";
}
}
小蓝车类:
public class BlueBike extends AbstractBike{
@Override
public String getColor() {
// TODO Auto-generated method stub
return "小蓝车";
}
}
享元工厂类(小车工厂类):
/*****
* 享元工厂类(单例)
* @author wjw
*
*/
public class BikeFactory {
private static final BikeFactory bikeFactory = new BikeFactory();
private Map<String,AbstractBike> bikes = new HashMap<String,AbstractBike>();
private BikeFactory(){
AbstractBike yellowBike = new YellowBike();
AbstractBike blueBike = new BlueBike();
bikes.put("yellow", yellowBike);
bikes.put("blue", blueBike);
}
public static BikeFactory getBikeFactory(){
return bikeFactory;
}
public AbstractBike getBike(String color){
if(bikes.containsKey(color.trim()) ){
return bikes.get(color.trim());
}else{
return null;
}
}
}
坐标类:
/*****
* 坐标类
* @author wjw
*
*/
public class Coordinate {
private int x;
private int y;
public Coordinate(int x,int y ){
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
Main类:
public class Main {
public static void main(String[] args) {
BikeFactory bikeFactory = BikeFactory.getBikeFactory();
AbstractBike yellowBike1 = bikeFactory.getBike("yellow");
AbstractBike yellowBike2 = bikeFactory.getBike("yellow");
AbstractBike blueBike1 = bikeFactory.getBike("blue");
AbstractBike blueBike2 = bikeFactory.getBike("blue");
yellowBike1.where(new Coordinate(1, 1));
yellowBike1.where(new Coordinate(2, 2));
blueBike1.where(new Coordinate(3, 3));
blueBike1.where(new Coordinate(4, 4));
System.out.println(yellowBike1 == yellowBike2);
System.out.println(blueBike1 == blueBike2 );
}
}
运行结果:
小黄车在(1,1)位置处。
小黄车在(2,2)位置处。
小蓝车在(3,3)位置处。
小蓝车在(4,4)位置处。
true
true
在享元模式中,有内部状态和外部状态一说,内部状态是享元对象的内部属性,也就是享元对象没了这个状态就不完整了,没法在面向对象编程界混了。在上面例子中,颜色就是小车的内部状态,位置就是小车的外部状态。一个小车出厂时就是涂了颜色出来的,而他的位置却是随时可变的,等待客户端赋给它。
结合JAVA中String字符串说一下,java中字符串就是使用了享元模式,String a = "aa"和String b = “aa”中a和b指向的内存地址相同,说明他们俩是一个对象,在这里这个字符串的“aa”就是他的内部状态。
“aa”存在哪里呢,用享元模式来说就是存在享元池中,如果我们再建新的字符串“ab”,享元池中没有,会向里添加“ab”。在我们小车例子中,用Map集合来简易代替小车享元池,不管取得多少小车,内存中就只有两个对象而已。
享元模式的目的是节约系统资源,提高系统性能。当系统中存在大量相同或相似对象时可以使用享元模式。
如有错误,欢迎指正
end