前言
本章讲解设计模式中享元模式的相关知识
方法
1.概念
不知道大家还记不记得之前学过的单例设计模式!
单例模式:保证一个类只有一个实例,并且提供一个访问该实例的全局访问点
单例模式保证的是该类的创建及其复杂的条件下,避免重复的创建而采用的设计模式,该类(属性)是固定的!
但是日常生活中一些对象之间有一些相对不变的属性和一些总是变化的属性。如围棋棋子:
那么关于棋子对象,它的属性颜色相对固定,只有黑色和白色,但是我们发现它的位置每个棋子是不一样的!
当我们不用享元模式去创建对象的时候,光黑色棋子的创建量就是巨大的,而且极其耗内存。
为了解决这个问题,我们推出了享元设计模式。
2.享元设计模式的实现思路
1)创建相应工程
2)创建享元类接口和享元实现类
package flyWeight;
/**
* 棋子享元接口
* @author jwang
*
*/
public interface IChessFlyWeight {
public String getColor();
public void display(ChessPosition chessPosition);
}
/**
* 棋子享元类
* @author jwang
*
*/
class ChessFlyWeight implements IChessFlyWeight{
private String color;//享元颜色(黑色、白色)
public ChessFlyWeight(String color) {
super();
this.color = color;
}
@Override
public String getColor() {
return this.color;
}
@Override
public void display(ChessPosition chessPosition) {
System.out.println("棋子的颜色:"+getColor());
System.out.println("棋子的位置:"+chessPosition.getX()+"---"+chessPosition.getY());
}
}
3)创建非共享属性类
package flyWeight;
/**
* 棋子非共享属性
* @author jwang
*
*/
public class ChessPosition {
private int x;
private int y;
public ChessPosition(int x, int y) {
super();
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;
}
}
4)创建享元类工厂
package flyWeight;
import java.util.HashMap;
import java.util.Map;
/**
* 享元工厂类
* @author jwang
*
*/
public class ChessFlyWeightFactory {
//key为棋子的颜色
private static Map<String,IChessFlyWeight> map = new HashMap<>();
public static IChessFlyWeight getChess(String color){
if(map.get(color)!=null){
return map.get(color);
}else {
IChessFlyWeight chessFlyWeight = new ChessFlyWeight(color);
map.put(color, chessFlyWeight);
return chessFlyWeight;
}
}
}
5)编写测试代码测试
package flyWeight;
public class Test {
public static void main(String[] args) {
IChessFlyWeight chess1 =ChessFlyWeightFactory.getChess("黑色");
IChessFlyWeight chess2 =ChessFlyWeightFactory.getChess("黑色");
System.out.println("是否为相同对象:"+(chess1==chess2));
//加入非共享属性
chess1.display(new ChessPosition(1, 2));
chess2.display(new ChessPosition(3, 4));
}
}
程序执行效果如下:
结论:
在一百个黑色棋子同时创建的情况下,使用享元模式仅仅在内存中创造了一个对象,大大节省了内存的开支。
但是由于在加入非共享属性时需要执行相关代码,所以相对来讲的消耗时间要久一些,即所谓“时间换空间”