Java设计模式-享元模式(12)

简介: Java设计模式-享元模式(12)

大家好,我是馆长!今天开始我们讲的是结构型模式中的享元模式。老规矩,讲解之前再次熟悉下结构型模式包含:代理模式、适配器模式、桥接模式、装饰器模式、外观模式、享元模式、组合模式,共7种设计模式。

享元模式(Flyweight Pattern)

定义

享元(Flyweight)模式的定义:运用共享技术来有效地支持大量细粒度对象的复用。它通过共享已经存在的对象来大幅度减少需要创建的对象数量、避免大量相似类的开销,从而提高系统资源的利用率。解决创建大量相同或相似对象实例的问题。

解决问题

创建大量相同或相似对象实例的问题。创建那么多的对象将会耗费很多的系统资源,它是系统性能提高的一个瓶颈,在有大量对象时,有可能会造成内存溢出,如果把它们相同的部分提取出来共享,则能节省大量的系统资源,我们把其中共同的部分抽象出来,如果有相同的业务请求,直接返回在内存中已有的对象,避免重新创建。

实现

内部状态:即不会随着环境的改变而改变的可共享部分。

外部状态:指随环境改变而改变的不可以共享的部分。

享元模式的实现要领就是区分应用中的这两种状态,并将外部状态外部化。下面来分析其基本结构和实现方法。

结构

主要角色:

抽象享元角色(Flyweight):是所有的具体享元类的基类,为具体享元规范需要实现的公共接口,非享元的外部状态以参数的形式通过方法传入。

具体享元(Concrete Flyweight)角色:实现抽象享元角色中所规定的接口。

非享元(Unsharable Flyweight)角色:是不可以共享的外部状态,它以参数的形式注入具体享元的相关方法中。

享元工厂(Flyweight Factory)角色:负责创建和管理享元角色。当客户对象请求一个享元对象时,享元工厂检查系统中是否存在符合要求的享元对象,如果存在则提供给客户;如果不存在的话,则创建一个新的享元对象。

应用场景:

系统中存在大量相同或相似的对象,这些对象耗费大量的内存资源。

大部分的对象可以按照内部状态进行分组,且可将不同部分外部化,这样每一个组只需保存一个内部状态【数据分离形态】。

需要缓冲池的场景。

注意:

注意划分外部状态和内部状态,否则可能会引起线程安全问题。

这些类必须有一个工厂对象加以控制,控制对象的维护和获取,以及其他的业务设定。

由于享元模式需要额外维护一个保存享元的数据结构,所以应当在有足够多的享元实例时才值得使用享元模式。

优点:

相同对象只要保存一份,这降低了系统中对象的数量,从而降低了系统中细粒度对象给内存带来的压力。

大大减少对象的创建,降低系统的内存,使效率提高。

缺点:

为了使对象可以共享,需要将一些不能共享的状态外部化,这将增加程序的复杂性。

读取享元模式的外部状态会使得运行时间稍微变长。

代码实现:模拟在坐标系中绘制图形。

//抽象享元角色:Marker
public interface Maker {
void draw(Coordinate coordinate);
}
​​​​​​
//具体享元角色: CircleMaker
@Data
public class CircleMaker implements Maker {

@Override
public void draw(Coordinate coordinate) {
System.out.println("在X:"+coordinate.getX()+"Y:"+coordinate.getY()+"为圆点,绘制圆形");
}
}
​​​​​
//具体享元角色: RectangleMaker
@Data
public class RectangleMaker implements Maker {

@Override
public void draw(Coordinate coordinate) {
System.out.println("在X:"+coordinate.getX()+"Y:"+coordinate.getY()+"为中心点,绘制矩形");
}
}
​​​​​​​
//非享元角色:Coordinate
@Data
public class Coordinate {
private Double x;
private Double y;

Coordinate() {
}

Coordinate(Double x, Double y) {
this.x = x;
this.y = y;
}
}

​​​​​​​

//限定获取结构:只能获取这些类型
public enum MakerType {
Circle("CircleMaker"),Rectangle("RectangleMaker");

private String name;
MakerType(String name){
this.name=name;
}
}

​​
//享元工厂角色:MakerFactory
@Data
public class MakerFactory {
private Map pool = new HashMap();

//初始化
public static MakerFactory builder() {
return new MakerFactory();

}

private MakerFactory() {
}

public Maker get(MakerType type) {
if (pool.get(type) == null) {
System.out.println(type.name()+"被创建了");
switch (type) {
case Circle:
set(type, new CircleMaker());
break;
case Rectangle:
set(type, new RectangleMaker());
break;
default:
}
}else{
System.out.println(type.name()+"已创建,无需创建");
}

return pool.get(type);

}

private void set(MakerType type, Maker maker) {
pool.put(type, maker);
}
}

​​​​​
//模拟客户端:ClientDemo
public class ClientDemo {
public static void main(String[] args) {
MakerFactory makerFactory = MakerFactory.builder();
Maker c1 = makerFactory.get(MakerType.Circle);
c1.draw(new Coordinate(1.0, 3.0));
System.out.println("\n");

Maker c2 = makerFactory.get(MakerType.Circle);
c2.draw(new Coordinate(2.0, 4.0));
System.out.println("\n");

Maker r1 = makerFactory.get(MakerType.Rectangle);
r1.draw(new Coordinate(10.0, 30.0));
System.out.println("\n");

Maker r2 = makerFactory.get(MakerType.Rectangle);
r2.draw(new Coordinate(120.0, 130.0));

}
}

扩展

在实际使用过程中,有时候会稍加改变,即存在两种特殊的享元模式:单纯享元模式和复合享元模式:
(1)单纯享元模式:这种享元模式中的所有的具体享元类都是可以共享的,不存在非共享的具体享元类。

(2)复合享元模式:这种享元模式中的有些享元对象是由一些单纯享元对象组合而成的,它们就是复合享元对象。虽然复合享元对象本身不能共享,但它们可以分解成单纯享元对象再被共享。

好了,关于享元模式的说明,馆长就先讲到这里。谢谢各位看官!!

23 种设计模式不是孤立存在的,很多模式之间存在一定的关联关系,在大的系统开发中常常同时使用多种设计模式,或者模式与模式之间的组合进行生成更加强大的程序功能。

相关文章
|
3月前
|
设计模式 存储 Java
Java设计模式之享元模式详解
Java设计模式之享元模式详解
|
设计模式 存储 缓存
享元模式【Java设计模式】
享元模式【Java设计模式】
54 0
享元模式【Java设计模式】
|
4月前
|
设计模式 存储 缓存
聊聊Java设计模式-享元模式
享元(Flyweight)模式:顾名思义就是**被共享的单元**。意图是复用对象,节省内存,提升系统的访问效率。比如在红白机冒险岛游戏中的背景花、草、树木等对象,实际上是可以多次被不同场景所复用共享,也是为什么以前的游戏占用那么小的内存,却让我们感觉地图很大的原因。
40 3
聊聊Java设计模式-享元模式
|
11月前
|
设计模式 存储 缓存
设计模式~享元模式(flyweight)-09
目录 (1)优点: (2)缺点: (3)使用场景: (4)注意事项: (5)应用实例:
42 0
|
设计模式 存储 缓存
设计模式-结构型模式:享元模式
设计模式-结构型模式:享元模式
|
存储 设计模式 Java
浅谈JAVA设计模式之——享元模式(Flyweight)
运用共享技术有效地支持大量细粒度的对象。
131 0
浅谈JAVA设计模式之——享元模式(Flyweight)
|
设计模式 移动开发 NoSQL
设计模式 - 结构型模式_享元模式
享元⼯⼚的设计,在⼀些有⼤量᯿复对象可复⽤的场景下,使⽤此场景在服务端减少接⼝的调⽤,在客户端减少内存的占⽤。是这个设计模式的主要应⽤⽅式。
116 0
设计模式 - 结构型模式_享元模式
|
设计模式 存储 对象存储
GOF设计模式之享元模式(结构型代理模式)
GOF设计模式之享元模式(结构型代理模式)
GOF设计模式之享元模式(结构型代理模式)
|
设计模式 Java uml
【设计模式】Java设计模式 - 享元模式
享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。
124 0
|
设计模式 缓存 Java
Java设计模式 ->享元模式
Java设计模式 ->享元模式
100 0