享元模式,结构型模式,享元模式通过共享对象来减少重复对象的创建。从而提高系统的效率和性能。
在享元模型中对象被分为两个部分,内部状态和外部状态。
-
内部状态:内部状态存储在享元对象的内部,是不改变的,不随着外部环境变化而变化。
-
外部状态:存储在享元对象外部,会随着外部环境的变化而变化。
例如在俄罗斯方块游戏中,有 I、L、P 、O 等等各种形状的方块,每一种方块在一局游戏中会使用很多次,若每一次使用都创建一个新的方块对象就会占用很多资源。 这种情况下就应该使用享元模式。
我们可以将俄罗斯方块都抽象成一个抽象方块【AbstractBox】,每一种具体的方块都是在抽象方块的基础上进一步封装。这里 抽象方块就是内部状态,方块的形状就是外部状态。
享元模式中主要有3中角色
1、抽象享元角色 2、具体享元 3、享元工厂角色
代码实现:
1、创建抽象享元角色
public abstract class AbstractBox {
/**
* 获取方块的形状
**/
public abstract String getShape();
public void display() {
System.out.println("方块的形状为:" + this.getShape());
}
}
2、创建具体享元角色
public class IBox extends AbstractBox {
@Override
public String getShape() {
return "I";
}
}
public class LBox extends AbstractBox {
@Override
public String getShape() {
return "L";
}
}
public class OBox extends AbstractBox {
@Override
public String getShape() {
return "O";
}
}
public class PBox extends AbstractBox {
@Override
public String getShape() {
return "P";
}
}
3、创建享元工厂
public class BoxFactory {
private static Map<String ,AbstractBox> map;
private BoxFactory(){
map = new HashMap<>();
AbstractBox iBox = new IBox();
AbstractBox pBox = new PBox();
AbstractBox oBox = new OBox();
AbstractBox lBox = new LBox();
map.put("I",iBox);
map.put("P",pBox);
map.put("O",oBox);
map.put("L",lBox);
}
static {
final BoxFactory INSTANCE= new BoxFactory();
}
public static AbstractBox getBox(String shape){
return map.get(shape);
}
}
4、测试
public static void main(String[] args) {
AbstractBox ibox1 = BoxFactory.getBox("I");
AbstractBox ibox2 = BoxFactory.getBox("I");
AbstractBox pBox1 = BoxFactory.getBox("P");
ibox1.display();
ibox2.display();
pBox1.display();
}
//测试结果
方块的形状为:I
方块的形状为:I
方块的形状为:P
Process finished with exit code 0
优点:
-
极大减少内存中相似或相同对象数量,节约系统资源,提供系统性能
-
模式中的外部状态相对独立,且不影响内部状态
缺点: 为了使对象可以共享,需要将享元对象的部分状态外部化,分离内部状态和外部状态,使程序逻辑复杂。