上一篇:设计模式(十一)——外观模式
下一篇:设计模式(十三)——责任链模式
一、需求
1.1 官方解释和我的理解
官方解释: Use sharing to support large numbers of fine-grained objects efficiently.(使用共享对象可有效地支持大量的细粒度对象。)
我的理解: 亨元模式的最重要的一个点就是大量细粒度对象,
第一,新建细粒度对象不是在客户端而是封装好的,有工厂模式的想法;
第二,因为要新建大量细粒度对象是不现实的,多次new新建对象资源消耗大,所以新建前判断是否为空,有单例模式的想法;
所以,亨元模式=工厂模式+单例模式
参与者: AbstractFlyweight(抽象亨元类)、ConcreteFlyweight(具体亨元类)、UnsharedConcreteFlyweight(非共享具体享元类)、FlyweightFactory(享元工厂类)
类图:
1.2 各个问题
第一,共享对象和非共享对象
共享对象:通过共享亨元类SharedFlyWeight、亨元工厂类FlyWeightFactory、外部状态类ExtrinsicState共同实现
非共享对象:通过非共享类UnsharedFlyWeight,在客户端直接new就好了
第二,为什么需要非共享亨元类?
尽管我们大部分时间都是通过共享对象来减低内存消耗,但是个别时候需要体现对象之间的不同的时候,此时UnsharedFlyWeight非共享亨元类就有存在的必要了,用来解决不需要共享的部分的问题。
第三,什么是内部状态和外部状态?内部状态和外部状态的存储位置?
在享元对象内部并且不用随环境改变而改变的共享部分,成为享元对象的内部状态,而随环境改变而改变的、不可以共享的状态就是外部状态。
内部状态存储于ConcreteFlyweight对象之中,而外部状态两种方式:
1、直接在客户端给出,当调用Flyweight对象的操作时,将该状态传递给它。参见代码1
2、外部状态作为一个独立的类写出来通过参数传递给共享亨元类。参见代码2
在实际使用中,能够共享的内部状态是有限的,因此享元对象一般都设计为较小的对象,它所包含的内部状态较少,这种对象也成为细粒度对象。
第四,什么是亨元池?
亨元工厂中为了实现单例的效果而新建的一个局部集合框架,一般是hashmap或hashtable,因为键值对好操作。
二、代码
代码1——单纯亨元模式(外部状态客户端给出) 代码2——单纯亨元模式(外部状态自定义类)
代码1——单纯亨元模式(外部状态客户端给出):
package mypackage;
import java.util.HashMap;
public class DesignPatternDemo {
public static void main(String[] args) {
int extrinsicState=47;
FlyWeight flyWeight_Rectangle = FlyWeightFactory.getFlyWeight("Rectangle");
System.out.println("flyWeight_Rectangle: " + flyWeight_Rectangle);
flyWeight_Rectangle = FlyWeightFactory.getFlyWeight("Rectangle");
System.out.println("flyWeight_Rectangle: " + flyWeight_Rectangle);
flyWeight_Rectangle.operate(++extrinsicState);
System.out.println("=========================");
FlyWeight flyWeight_Circle=new UnSharedFlyWeight();
flyWeight_Circle.operate(++extrinsicState);
}
}
abstract class FlyWeight {
public abstract void operate(int extrinsicState);
}
class SharedFlyWeight extends FlyWeight {
private String intrinsic;
public SharedFlyWeight(String intrinsic) {
this.intrinsic = intrinsic;
}
@Override
public void operate(int extrinsicState) {
System.out.println("共享FlyWeight: " + intrinsic);
System.out.println("ExtrinsicState: " + extrinsicState);
}
}
class UnSharedFlyWeight extends FlyWeight {
@Override
public void operate(int extrinsicState) {
System.out.println("非共享FlyWeight ExtrinsicState: " + extrinsicState);
}
}
//兼顾工厂模式和单例模式思想 工厂模式:在工厂方法中new 单例模式:相同intrinsic仅new一次
class FlyWeightFactory {
private static HashMap<String, FlyWeight> pool = new HashMap<>();
public static FlyWeight getFlyWeight(String intrinsic) {
FlyWeight flyWeight = null;
if (pool.containsKey(intrinsic)) {
flyWeight = pool.get(intrinsic);
System.out.println("获取: " + flyWeight);
} else {
flyWeight = new SharedFlyWeight(intrinsic);
pool.put(intrinsic, flyWeight);
System.out.println("新建 : " + flyWeight + " ,并加入亨元池中");
}
return flyWeight;
}
}
输出1:
新建 : mypackage.SharedFlyWeight@15db9742 ,并加入亨元池中
flyWeight_Rectangle: mypackage.SharedFlyWeight@15db9742
获取: mypackage.SharedFlyWeight@15db9742
flyWeight_Rectangle: mypackage.SharedFlyWeight@15db9742
共享FlyWeight: Rectangle
ExtrinsicState: 48
=========================
非共享FlyWeight ExtrinsicState: 49
代码2——单纯亨元模式(外部状态自定义类) :
package mypackage;
import java.util.HashMap;
public class DesignPatternDemo {
public static void main(String[] args) {
FlyWeight flyWeight_Rectangle = FlyWeightFactory.getFlyWeight("Rectangle");
System.out.println("flyWeight_Rectangle: " + flyWeight_Rectangle);
flyWeight_Rectangle = FlyWeightFactory.getFlyWeight("Rectangle");
System.out.println("flyWeight_Rectangle: " + flyWeight_Rectangle);
flyWeight_Rectangle.operate(new ExtrinsicState("This is ExtrinsicState"));
System.out.println("=========================");
FlyWeight flyWeight_Circle=new UnSharedFlyWeight();
flyWeight_Circle.operate(new ExtrinsicState("This is ExtrinsicState"));
}
}
abstract class FlyWeight {
public abstract void operate(ExtrinsicState extrinsicState);
}
class SharedFlyWeight extends FlyWeight {
private String intrinsic;
public SharedFlyWeight(String intrinsic) {
this.intrinsic = intrinsic;
}
@Override
public void operate(ExtrinsicState extrinsicState) {
System.out.println("共享FlyWeight: " + intrinsic);
System.out.println("ExtrinsicState: " + extrinsicState.getExtrinsic());
}
}
//外部状态单独用一个类 写出来
class ExtrinsicState {
private String extrinsic;
public String getExtrinsic() {
return extrinsic;
}
public void setExtrinsic(String extrinsic) {
this.extrinsic = extrinsic;
}
public ExtrinsicState(String extrinsic) {
this.extrinsic = extrinsic;
}
}
class UnSharedFlyWeight extends FlyWeight {
@Override
public void operate(ExtrinsicState extrinsicState) {
System.out.println("非共享FlyWeight ExtrinsicState: " + extrinsicState.getExtrinsic());
}
}
//兼顾工厂模式和单例模式思想 工厂模式:在工厂方法中new 单例模式:相同intrinsic仅new一次
class FlyWeightFactory {
private static HashMap<String, FlyWeight> pool = new HashMap<>();
public static FlyWeight getFlyWeight(String intrinsic) {
FlyWeight flyWeight = null;
if (pool.containsKey(intrinsic)) {
flyWeight = pool.get(intrinsic);
System.out.println("获取: " + flyWeight);
} else {
flyWeight = new SharedFlyWeight(intrinsic);
pool.put(intrinsic, flyWeight);
System.out.println("新建 : " + flyWeight + " ,并加入亨元池中");
}
return flyWeight;
}
}
输出2:
新建 : mypackage.SharedFlyWeight@15db9742 ,并加入亨元池中
flyWeight_Rectangle: mypackage.SharedFlyWeight@15db9742
获取: mypackage.SharedFlyWeight@15db9742
flyWeight_Rectangle: mypackage.SharedFlyWeight@15db9742
共享FlyWeight: Rectangle
ExtrinsicState: This is ExtrinsicState
=========================
非共享FlyWeight ExtrinsicState: This is ExtrinsicState
三、小结
亨元模式:
1、新建对象是吸收了工厂模式和单例模式的思想,减少内存消耗。
2、内部状态位于亨元对象中,和亨元类绑定;外部状态独立出来,可以在客户端,可以是一个独立类,不与亨元类绑定。
3、亨元工厂类中只创建共享亨元类,非共享亨元类在客户端独立创建,和亨元工厂无关。
上一篇:设计模式(十一)——外观模式
下一篇:设计模式(十三)——责任链模式