本文介绍享元模式思想、以及与单例模式的使用联系
简介
Flyweight模式也叫享元模式,是构造型模式的一种
通过与其他类似对象共享数据来减小内存占用
结构图
角色和职责
- 抽象享元角色:所有具体享元类的父类,规定一些需要实现的公共接口。
- 具体享元角色:抽象享元角色的具体实现类,并实现了抽象享元角色规定的方法。
- 享元工厂角色:负责创建和管理享元角色
实现
抽象对象
package com.mym.designmodel.Flyweight;
/**
* 职责:抽象享元角色
*/
public class Person {
private int id;
private String name;
private int gender;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getGender() {
return gender;
}
public void setGender(int gender) {
this.gender = gender;
}
}
具体享元对象
package com.mym.designmodel.Flyweight;
/**
* 职责:具体享元角色
*/
public class Student extends Person{
private int number;
public Student(int number) {
this.number = number;
}
public Student(int number, int id, String name, int gender){
this.number = number;
this.setId(id);
this.setName(name);
this.setGender(gender);
}
public int getNumber() {
return number;
}
}
享元工厂
package com.mym.designmodel.Flyweight;
import java.util.HashMap;
import java.util.Map;
/**
* 职责:享元工厂角色
*/
public class StudentFactory {
private Map<Integer, Student> studentMap;
public StudentFactory() {
this.studentMap = new HashMap<Integer, Student>();
}
public Student getStudent(int number){
Student student = studentMap.get(number);
if(student == null){
student = new Student(number);
studentMap.put(number,student);
}
return student;
}
}
注,享元工厂的设计中,map的key实际上更应该是Person中的一个字段来标识,总之,明白模式思想就好
测试
package com.mym.designmodel.Flyweight;
public class MainClass {
public static void main(String[] args) {
Student stu1 = new Student(1);
Student stu2 = new Student(2);
Student stu3 = new Student(2);
Student stu4 = new Student(3);
System.out.println("stu1 :"+stu1.getNumber());
System.out.println("stu2 :"+stu2.getNumber());
System.out.println("stu3 :"+stu3.getNumber());
System.out.println("stu4 :"+stu4.getNumber());
System.out.println("非享元模式中 stu2 == stu3 :"+ (stu2 == stu3));
System.out.println("---------------------------------------------------");
StudentFactory studentFactory = new StudentFactory();
Student student1 = studentFactory.getStudent(1);
Student student2 = studentFactory.getStudent(2);
Student student3 = studentFactory.getStudent(3);
Student student4 = studentFactory.getStudent(1);
System.out.println("student1 :"+student1.getNumber());
System.out.println("student2 :"+student2.getNumber());
System.out.println("student3 :"+student3.getNumber());
System.out.println("student4 :"+student4.getNumber());
System.out.println("享元模式中 student1 == student4 :"+ (student1 == student4));
}
}
结果:
stu1 :1
stu2 :2
stu3 :2
stu4 :3
非享元模式中 stu2 == stu3 :false
---------------------------------------------------
student1 :1
student2 :2
student3 :3
student4 :1
享元模式中 student1 == student4 :true
享元与单例
享元模式关注的是内存共享,但是内存安全共享其实有个前提条件就是保证对象”单例”创建。看享元工厂逻辑可知,new 对象其实不是线程安全的,这个使用此模式时需要了解到
如果业务逻辑允许,可以给new这个过程做一个单例