通过使用池的技术,有效减少了大量
细粒度
的对象的重复生成。
0x00 组织结构
- Flyweight:抽象享元类,声明了可以想外界提供内部状态的方法,同时还可以设置外部状态。
- ConcreteFlyweight:具体享元类,通常和单例模式组合使用。
- UnsharedConcreteFlyweight(非共享具体享元类):并不是所有的抽象享元类的子类都需要被共享,不能被共享的子类可设计为非共享具体享元类;当需要一个非共享具体享元类的对象时可以直接通过实例化创建。
- FlyweightFactory:享元池,享元池一般设计为一个存储“键值对”的集合,可以结合工厂模式进行设计。
0x01 示例
以组装PC为例,其中CPU充当内部状态,Computer充当外部状态。
package com.kkk.pattern.flyweight;
/**
* 充当享元类
* Created by z3jjlzt on 2018/1/10.
*/
public abstract class CPU {
//获取内部状态
public abstract String getCPUName();
//注入外部状态
public void setComputer(Computer computer) {
System.out.println("把型号为 " + getCPUName() + "的cpu安装在型号为 " + computer + "的电脑上");
}
}
/**
* 充当具体享元
* Created by z3jjlzt on 2018/1/10.
*/
public class AMDCPU extends CPU {
private AMDCPU() {}
private static class Instance{
private static final AMDCPU cpu = new AMDCPU();
}
public static AMDCPU getInstance() {
return Instance.cpu;
}
@Override
public String getCPUName() {
return "AMD";
}
}
/**
* 充当具体享元
* Created by z3jjlzt on 2018/1/10.
*/
public class IntelCPU extends CPU {
private IntelCPU() {}
private static class Instance{
private static final IntelCPU cpu = new IntelCPU();
}
public static IntelCPU getInstance() {
return Instance.cpu;
}
@Override
public String getCPUName() {
return "Intel";
}
}
/**
* 充当外部状态
* Created by z3jjlzt on 2018/1/10.
*/
public class Computer {
private String name;
public Computer(String name) {
this.name = name;
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("Computer{");
sb.append("name='").append(name).append('\'');
sb.append('}');
return sb.toString();
}
}
import java.util.HashMap;
/**
* 充当共享池
* Created by z3jjlzt on 2018/1/10.
*/
public class CPUFactory {
private static HashMap<String, CPU> fpool = new HashMap<>();
private CPUFactory() {
}
private static class Instance {
private static final CPUFactory cf = new CPUFactory();
}
public static CPUFactory getInstance() {
return Instance.cf;
}
public static CPU getCPU(String type) {
if (null == fpool.get(type)) {
switch (type) {
case "AMD":
fpool.put("AMD", AMDCPU.getInstance());
break;
case "Intel":
fpool.put("Intel", IntelCPU.getInstance());
break;
default:
break;
}
}
return fpool.get(type);
}
}
/**
* Created by z3jjlzt on 2018/1/10.
*/
public class Client {
public static void main(String[] args) {
CPUFactory cpuFactory = CPUFactory.getInstance();
CPU amd1 = cpuFactory.getCPU("AMD");
CPU amd2 = cpuFactory.getCPU("AMD");
CPU intel1 = cpuFactory.getCPU("Intel");
System.out.println(amd1 == amd2);
System.out.println(amd1 == intel1);
amd1.setComputer(new Computer("新华同方"));
intel1.setComputer(new Computer("华硕"));
}
}
结果:
package com.kkk.pattern.flyweight;
/**
* 充当享元类
* Created by z3jjlzt on 2018/1/10.
*/
public abstract class CPU {
//获取内部状态
public abstract String getCPUName();
//注入外部状态
public void setComputer(Computer computer) {
System.out.println("把型号为 " + getCPUName() + "的cpu安装在型号为 " + computer + "的电脑上");
}
}
/**
* 充当具体享元
* Created by z3jjlzt on 2018/1/10.
*/
public class AMDCPU extends CPU {
private AMDCPU() {}
private static class Instance{
private static final AMDCPU cpu = new AMDCPU();
}
public static AMDCPU getInstance() {
return Instance.cpu;
}
@Override
public String getCPUName() {
return "AMD";
}
}
/**
* 充当具体享元
* Created by z3jjlzt on 2018/1/10.
*/
public class IntelCPU extends CPU {
private IntelCPU() {}
private static class Instance{
private static final IntelCPU cpu = new IntelCPU();
}
public static IntelCPU getInstance() {
return Instance.cpu;
}
@Override
public String getCPUName() {
return "Intel";
}
}
/**
* 充当外部状态
* Created by z3jjlzt on 2018/1/10.
*/
public class Computer {
private String name;
public Computer(String name) {
this.name = name;
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("Computer{");
sb.append("name='").append(name).append('\'');
sb.append('}');
return sb.toString();
}
}
import java.util.HashMap;
/**
* 充当共享池
* Created by z3jjlzt on 2018/1/10.
*/
public class CPUFactory {
private static HashMap<String, CPU> fpool = new HashMap<>();
private CPUFactory() {
}
private static class Instance {
private static final CPUFactory cf = new CPUFactory();
}
public static CPUFactory getInstance() {
return Instance.cf;
}
public static CPU getCPU(String type) {
if (null == fpool.get(type)) {
switch (type) {
case "AMD":
fpool.put("AMD", AMDCPU.getInstance());
break;
case "Intel":
fpool.put("Intel", IntelCPU.getInstance());
break;
default:
break;
}
}
return fpool.get(type);
}
}
/**
* Created by z3jjlzt on 2018/1/10.
*/
public class Client {
public static void main(String[] args) {
CPUFactory cpuFactory = CPUFactory.getInstance();
CPU amd1 = cpuFactory.getCPU("AMD");
CPU amd2 = cpuFactory.getCPU("AMD");
CPU intel1 = cpuFactory.getCPU("Intel");
System.out.println(amd1 == amd2);
System.out.println(amd1 == intel1);
amd1.setComputer(new Computer("新华同方"));
intel1.setComputer(new Computer("华硕"));
}
}
结果:
true
false
把型号为 AMD的cpu安装在型号为 Computer{name='新华同方'}的电脑上
把型号为 Intel的cpu安装在型号为 Computer{name='华硕'}的电脑上
0xff 总结
- 优点:大大减少相同对象的数量,内外部状态互相独立。
- 缺点:需要区分内外部状态,增加系统设计难度。
- 适用场景:一个系统有大量相同或者相似的对象,造成内存的大量耗费。