JAVA设计模式之享元模式
概念:
在一个系统中如果有多个相同的对象,那么只共享一份就可以了,不必每个都去实例化一个对象。比如说一个文本系统,每个字母定一个对象,那么大小写字母一共就是52个,那么就要定义52个对象。如果有一个1M的文本,那么字母是何其的多,如果每个字母都定义一个对象那么内存早就爆了。那么如果要是每个字母都共享一个对象,那么就大大节约了资源。
在Flyweight模式中,由于要产生各种各样的对象,所以在Flyweight(享元)模式中常出现Factory模式。Flyweight的内部状态是用来共享的,Flyweight factory负责维护一个对象存储池(Flyweight Pool)来存放内部状态的对象。Flyweight模式是一个提高程序效率和性能的模式,会大大加快程序的运行速度.
享元模式以共享的方式高效的支持大量细粒度对象的重用。
享元模式能做到共享的关键是区分内部状态和外部状态。内部状态:可以共享,不会随环境变化而变化;外部状态:不可以共享,会随环境变化而改变。
角色
-FlyweightFactory享元工厂类:创建并管理享元对象,享元池一般设计成键值对
-Flyweight抽象享元类:通常是一个接口或抽象类,声明公共方法,这些方法可以向外界提供对象的内部状态,设置外部状态。
-ConcreteFlyWeight具体享元类:为内部状态提供成员变量进行存储
-UnsharedConcreteFlyWeight非共享享元类:不能被共享的子类可以设计为非共享享元类
类图
应用
享元模式由于其共享特性,可以在任何“池”中操作,比如:线程池、数据库连接池。
String类的设计也是享元模式。
代码
Flyweight抽象享元类,具体享元类
//Flyweight抽象享元类
public interface ChessFlyWeight {
void setColor(String color);
String getColor();
void display(Coordinate c);
}
//ConcreteFlyWeight具体享元类
class ConcreteChess implements ChessFlyWeight {
private String color;
public ConcreteChess(String color) {
super();
this.color = color;
}
@Override
public void setColor(String color) {
}
@Override
public String getColor() {
return color;
}
@Override
public void display(Coordinate c) {
System.out.println("color: " + color);
System.out.println("coordinate: " + c.getX() + " " + c.getY());
}
}
外部状态UnsharedConcreteFlyWeight
//外部状态UnsharedConcreteFlyWeight
public class Coordinate {
private int x, 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;
}
}
享元工厂类
// 享元工厂类
public class ChessFlyWeightFactory {
// 享元池
private static Map
总结
优点
- 极大的减少内存对象的数量;
- 相同或相似的对象内存只存一份,极大的节约资源,提高系统性能;
- 外部状态相对独立,不影响内部状态
缺点
1. 模式较复杂,使程序逻辑复杂化
2. 为了节省内存,共享内部状态,分离外部状态,而读取外部状态使运行时间变长。用时间换取空间。