1 享元模式介绍
2 享元模式原理
3 享元模式实现
抽象享元类可以是一个接口也可以是一个抽象类,作为所有享元类的公共父类, 主要作用是提高系统的可扩展性.
java
//* 抽象享元类
public abstract class Flyweight {
public abstract void operation(String extrinsicState);
}
具体享元类
具体享元类中要将内部状态和外部状态分开处理,内部状态作为具体享元类的成员变量,而外部状态通过注入的方式添加到具体享元类中.
java
/**
* 可共享的-具体享元类
* 注意: 在具体享元类中,需要将内部状态和外部状态分开处理.
**/
public class ConcreteFlyweight extends Flyweight{
//内部状态 : inState作为一个成员变量,同一个享元对象的内部状态是一致的.
private String inState;
public ConcreteFlyweight(String inState) {
this.inState = inState;
}
/**
* 外部状态在使用的时候,通常是有外部设置,不保存在享元对象中,即使是同一个对象
* @param state
*/
@Override
public void operation(String state) {
System.out.println("=== 享元对象的内部状态: " + inState + ",外部状态: " + state );
}
}
非共享享元类,不复用享元工厂内部状态,但是是抽象享元类的子类或实现类
java
/**
* 非共享的具体享元类
**/
public class UnsharedFlyweight extends Flyweight{
private String inState;
public UnsharedFlyweight(String inState) {
this.inState = inState;
}
@Override
public void operation(String state) {
System.out.println("=== 使用不共享对象,内部状态: " + inState + ",外部状态: " + state );
}
}
享元工厂类, 管理一个享元对象类的缓存池。它会存储享元对象之间需要传递的共有状态,比如,按照大写英文字母来作为状态标识,这种只在享元对象之间传递的方式就叫内部状态。同时,它还提供了一个通用方法getFlyweight(),主要通过内部状态标识来获取享元对象。
java
/**
* 享元工厂类
* 作用: 作为存储享元对象的享元池.用户获取享元对象时先从享元池中获取,有则返回,没有创建新的返回给用户,
* 并且在享元池中保存
**/
public class FlyweightFactory {
//定义一个Map集合用于存储享元对象,实现享元池
private Map<String,Flyweight> pool = new HashMap<>();
//实现享元对象之间的状态传递
public FlyweightFactory() {
//添加对应的内部状态
pool.put("A",new ConcreteFlyweight("A"));
pool.put("B",new ConcreteFlyweight("B"));
pool.put("C",new ConcreteFlyweight("C"));
}
//根据内部状态进行查找
public Flyweight getFlyweight(String key){
//对象是否存在
if(pool.containsKey(key)){
System.out.println("=== 享元池中存在,直接复用,key : " + key);
return pool.get(key);
}else{
//如果对象不存在,就创建一个添加到享元池,然后返回
System.out.println("=== 享元池中不存在,创建并复用,key: " + key);
Flyweight fw = new ConcreteFlyweight(key);
pool.put(key,fw);
return fw;
}
}
}
java
public class Client {
public static void main(String[] args) {
//获取工厂对象
FlyweightFactory factory = new FlyweightFactory();
//通过工厂对象获取共享的享元对象
Flyweight a1 = factory.getFlyweight("A");
a1.operation("a1ExState");
Flyweight a2 = factory.getFlyweight("A");
a2.operation("a2ExState");
System.out.println(a1 == a2);
//获取非共享的享元对象
UnsharedFlyweight u1 = new UnsharedFlyweight("A");
UnsharedFlyweight u2 = new UnsharedFlyweight("A");
System.out.println(u1 == u2);
}
}
4 享元模式应用实例
java
/**
* 抽象享元类: 五子棋
**/
public abstract class GobangFlyweight {
public abstract String getColor();
public void display(){
System.out.println("棋子颜色: " + this.getColor());
}
}
java
/**
* 共享享元类-白色棋子
**/
public class WriteGobang extends GobangFlyweight {
@Override
public String getColor() {
return "白色";
}
}
java
/**
* 共享享元类-黑色棋子
**/
public class BlackGobang extends GobangFlyweight {
@Override
public String getColor() {
return "黑色";
}
}
java
/**
* 享元工厂类-生产五子棋棋子
**/
public class GobangFactory {
//享元池
private static Map<String,GobangFlyweight> pool;
//创建共享享元对象,设置对象的内部状态
private GobangFactory() {
pool = new HashMap<>();
GobangFlyweight black = new BlackGobang(); //黑子
GobangFlyweight write = new WriteGobang(); //白子
pool.put("b",black);
pool.put("w",write);
}
//获取唯一享元工厂对象的方法
public static GobangFactory getInstance(){
return SingletonHolder.INSTANCE;
}
//静态内部类
private static class SingletonHolder{
private static final GobangFactory INSTANCE = new GobangFactory();
}
//通过key获取集合中的享元对象
public GobangFlyweight getGobang(String key){
return pool.get(key);
}
}
java
public class Client {
public static void main(String[] args) {
GobangFactory instance = GobangFactory.getInstance();
//获取3颗黑子
GobangFlyweight b1 = instance.getGobang("b");
GobangFlyweight b2 = instance.getGobang("b");
GobangFlyweight b3 = instance.getGobang("b");
System.out.println("判断黑子是否是同一对象: " + (b1 == b2));
GobangFlyweight w1 = instance.getGobang("w");
GobangFlyweight w2 = instance.getGobang("w");
System.out.println("判断白子是否是同一对象: " + (w1 == w2));
//显示棋子
b1.display();
b2.display();
b3.display();
w1.display();
w2.display();
}
}
5 享元模式总结