成功就是百分之一的天赋加上百分之九十九的努力
享元模式(flyweight)
1.模式定义:
运用共享技术有效地支持大量细粒度的对象
节省CPU资源,内存空间
2.适用对象:
使用频率高的对象,并且线程安全,不可变对,数据一致性的对象适合共享操作
接下来我们通过代码来了解一下享元模式的底层理念:
//首先定义一个main方法类
public class FlyWeightTest{
public static void main(String[] args){
//接下来我们来验证一下,是否能实现共享
Tree tree= TreeFactory.getTree("xxx","xxxx");
Tree tree1= TreeFactory.getTree("xxx","xxxx");
Tree tree2= TreeFactory.getTree("xxx","xxxx");
//运行程序我们会发现在控制台会出现一次创建两次使用,这就是享元模式的底层基础
}
}
/** 我们来假设一个场景,我们需要做一个游戏的页面,在该页面中需要一片树木,这些树呢其实都差不多,很类似,只不过通过不同的排列组合制造出一种不尽相同的效果,,当我们需要1000棵树的时候,如果一个一个new是特别浪费资源的,那么我们是不是就可以考虑使用享元模式,节省内存资源,CPU资源,(先理解场景)
*/
//基于上述场景,我们先来定义一个树类
class Tree{
//名字,实现公用,就不需要频繁更改,所以用final修饰
private final String name;
private final String data; //其他信息
public Tree(String name,String data){
this.name=name;
this.data=data;
}
public String getName(){
return name;
}
public String getData(){
return data;
}
}
//还需要定义一个地图类
class TreeNode{
private int x;
private int y;
private Tree tree;//导包
public TreeNode(int x,int y,Tree tree){
this.x=x;
this.y=y;
this.tree=tree;
}
public int getX(){
return x;
}
public int y getY(){
return y;
}
public Tree getTree(){
return tree;
}
}
//接下来是重点不要眨眼,我们需要创建一个容器,来实现树创建的共享
class TreeFactory{
//创建容器
private static Map<String,Tree>map=new ConcurrentHashMap<>();
//提供全局访问点
public static Tree getTree(String name,String data){
if(map.containsKey(name)){
Sytem.out.println("使用共享Tree");
return map.get(name);
}
//不存在对应的key值则重新创建
Tree tree =new Tree(name,data);
Sytem.out.println("创建Tree");
map.put(name,tree);
return tree;
}
}
以上内容就是享元模式的基础,通过将共享对象存入容器内,实现数据的共享,通过底层逻辑判断实现了单例模式的创建,但是事实上在一定程度上还是存在线程安全问题,例如:多线程同时在第一次去调用getTree()方法,大家可以去研究一下,
没有十全十美的方法和设计模式,但是程序的魅力就在这个地方,总有让你不断完善的地方,总能让你体会到前进的快乐,加油!