版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_40646143/article/details/85242230
使用场景
- 内存属于稀缺资源,不要随便浪费 , 如果有很多个完全相同或相似的对象 ,我们可以通过享元模式,节省内存。
享元模式的核心:
- 享元模式以共享的放式高效地支持大量细粒度对象的重用。
- 享元对象能做到共享的关键是区分了内部状态和外部状态。
- 1),内部状态 :可以共享 ,不会随着环境变化而改变 。
- 2),外部状态: 不可以共享,会随着环境变化而改变。
例如下面这个围棋
享元模式的实现:
- FlyWeightFactory享元工厂类 --创建并管理享元对象,享元池一般设计成键值对
- FlyWeight 抽象享元类 -- 通常是一个接口或抽象类,申明公共方法, 这些方法可以向外界提供对象的内部状态,设置外部状态
- ConcreteFlyWeight 具体享元类 --为内部状态提供成员变量进行存储
- UnsharedConcreteFlyWeight 非共享享元类 -- 不能被共享的子类可以设计为非共享享元类
接下来用代码来实现上面的例子
1),创建抽象享元类接口 与创建具体享元类
/**
*享元接口类
*/
public interface ChessFlyWeight {
void position(ChessPosition chessPosition);
String getColor();
}
/**ConcreteFlyWeight
* 共享享元类
*/
class ConcreteChess implements ChessFlyWeight{
private String color;
public ConcreteChess(String color) {
this.color = color;
}
@Override
public void position(ChessPosition chessPosition) {
System.out.println("棋子颜色是:"+color);
System.out.println("棋子位置:" + chessPosition.getX() + "-->" + chessPosition.getY());
}
@Override
public String getColor() {
return color;
}
}
2),创建非共享享元类
/**UnsharedConcreteFlyWeight
* 非共享享元类
* @author 晓电脑
*/
public class ChessPosition {
private int x;
private int y;
public ChessPosition(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;
}
}
3),创建享元工厂类
/**享元工厂类
* FlyWeightFactory
* @author 晓电脑
*/
public class ChessFlyWeightFactory {
private static Map<String,ChessFlyWeight> map=new HashMap<>();
public static ChessFlyWeight getChess(String color){
if (map.get(color) != null){
return map.get(color);
}else {
ChessFlyWeight weight = new ConcreteChess(color);
map.put(color,weight);
return weight;
}
}
}
4),创建客户端进行测试
/**客户端进行测试
* @author 晓电脑
*/
public class Client {
public static void main (String[] args) {
ChessFlyWeight chess = ChessFlyWeightFactory.getChess("黑色");
ChessFlyWeight chess1 = ChessFlyWeightFactory.getChess("黑色");
System.out.println(chess);
System.out.println(chess1);
System.out.println("增加外部处理 位置的变换");
chess.position(new ChessPosition(10,10));
chess.position(new ChessPosition(20,20));
}
}
运行结果
总结:棋子的颜色颜色实现了共享,返回的都是一个对象,棋子的外部状态发生了改变,因为你每次都是从外部传进来的,这样可以用一个专门的类进行处理,这样外部状态和内部状态进行了分离,相互不影响
享元模式开发中应用的场景:
- 享元模式由于其共享的特性,可以在任何 池 中操作 , 比如线程池 ,数据库连接池等
- String类的设计也是享元模式
享元模式的uml类图如下