享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。
意图:运用共享技术有效地支持大量细粒度的对象。
面向对象技术可以很好地解决一些灵活性或可扩展性问题,但在很多情况下需要在系统中增加类和对象的个数。当对象数量太多时,将导致运行代价过高,带来性能下降等问题。享元模式正是为解决这一类问题而诞生的
在享元模式中可以共享的相同内容称为 内部状态(Intrinsic State),而那些需要外部环境来设置的不能共享的内容称为 外部状态(Extrinsic State),其中外部状态和内部状态是相互独立的,外部状态的变化不会引起内部状态的变化。由于区分了内部状态和外部状态,因此可以通过设置不同的外部状态使得相同的对象可以具有一些不同的特征,而相同的内部状态是可以共享的。也就是说,享元模式的本质是分离与共享 : 分离变与不变,并且共享不变。把一个对象的状态分成内部状态和外部状态,内部状态即是不变的,外部状态是变化的;然后通过共享不变的部分,达到减少对象数量并节约内存的目的。
享元模式的目的就是使用共享技术来实现大量细粒度对象的复用
主要解决:在有大量对象时,有可能会造成内存溢出,我们把其中共同的部分抽象出来,如果有相同的业务请求,直接返回在内存中已有的对象,避免重新创建。
何时使用: 1、系统中有大量对象。 2、这些对象消耗大量内存。 3、这些对象的状态大部分可以外部化。 4、这些对象可以按照内蕴状态分为很多组,当把外蕴对象从对象中剔除出来时,每一组对象都可以用一个对象来代替。 5、系统不依赖于这些对象身份,这些对象是不可分辨的。
如何解决:用唯一标识码判断,如果在内存中有,则返回这个唯一标识码所标识的对象。
关键代码:用 HashMap 存储这些对象。
应用实例: 1、JAVA 中的 String,如果有则返回,如果没有则创建一个字符串保存在字符串缓存池里面。 2、数据库的数据池。
优点:大大减少对象的创建,降低系统的内存,使效率提高。
缺点:提高了系统的复杂度,需要分离出外部状态和内部状态,而且外部状态具有固有化的性质,不应该随着内部状态的变化而变化,否则会造成系统的混乱。
使用场景: 1、系统有大量相似对象。 2、需要缓冲池的场景。
注意事项: 1、注意划分外部状态和内部状态,否则可能会引起线程安全问题。 2、这些类必须有一个工厂对象加以控制。
享元模式:主要角色由享元工厂、抽象享元、具体享元类几部分组成
模式所涉及的角色
Flyweight: 享元接口,通过这个接口传入外部状态并作用于外部状态;
ConcreteFlyweight: 具体的享元实现对象,必须是可共享的,需要封装享元对象的内部状态;
UnsharedConcreteFlyweight: 非共享的享元实现对象,并不是所有的享元对象都可以共享,非共享的享元对象通常是享元 对 象的组合对象;
FlyweightFactory: 享元工厂,主要用来创建并管理共享的享元对象,并对外提供访问共享享元的接口;
享元模式的核心在于享元工厂类,享元工厂类的作用在于提供一个用于存储享元对象的享元池,用户需要对象时,首先从享元池中获取,如果享元池中不存在,则创建一个新的享元对象返回给用户,并在享元池中保存该新增对象。
步骤 1
/*
抽象享元角色——抽象公共接口
*/
public abstract class Flyweight {
public abstract void State(String state);
}
步骤 2
/*
具体享元角色——实现其具体
*/
public class ConcreteFlyweight extends Flyweight{
String realization;
/*
构造函数 内部状态参数传入
*/
public ConcreteFlyweight(String start) {
this.realization=start;
}
/*
实现方法
*/
@Override
public void State(String state) {
System.out.println("内部状态:"+realization+"外部状态:"+state);
}
}
步骤 3
import java.util.HashMap;
/*
享元工厂角色——对享元角色进行创建及管理的
*/
public class FlyweightFactory {
private static final HashMap<String, ConcreteFlyweight> circleMap = new HashMap<>();
public ConcreteFlyweight getRealizationFlyweight(String start) {
ConcreteFlyweight circle = circleMap.get(start);
if(circle==null) {
circle=new ConcreteFlyweight(start);
circleMap.put(start,circle);
}
return circle;
}
}
步骤 4
/*
享元模式(Flyweight Pattern)
*/
public class FlyweightPatternDescription {
public static void main(String[] args) {
FlyweightFactory factory = new FlyweightFactory();
ConcreteFlyweight flyweight=factory.getRealizationFlyweight("成功");
flyweight.State("成功状态");
flyweight=factory.getRealizationFlyweight("失败");
flyweight.State("失败状态");
flyweight=factory.getRealizationFlyweight("成功");
flyweight.State("已成功");
}
}
结果:
内部状态:成功外部状态:成功状态
内部状态:失败外部状态:失败状态
内部状态:成功外部状态:已成功
原文:https://www.cnblogs.com/shu-java-net/p/13357002.html