设计模式(十二)——亨元模式

199 阅读4分钟

上一篇:设计模式(十一)——外观模式

下一篇:设计模式(十三)——责任链模式

一、需求

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、亨元工厂类中只创建共享亨元类,非共享亨元类在客户端独立创建,和亨元工厂无关。

 

上一篇:设计模式(十一)——外观模式

下一篇:设计模式(十三)——责任链模式