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

相关文章
|
17天前
|
设计模式 消息中间件 搜索推荐
Java 设计模式——观察者模式:从优衣库不使用新疆棉事件看系统的动态响应
【11月更文挑战第17天】观察者模式是一种行为设计模式,定义了一对多的依赖关系,使多个观察者对象能直接监听并响应某一主题对象的状态变化。本文介绍了观察者模式的基本概念、商业系统中的应用实例,如优衣库事件中各相关方的动态响应,以及模式的优势和实际系统设计中的应用建议,包括事件驱动架构和消息队列的使用。
|
28天前
|
设计模式 Java 数据库连接
Java编程中的设计模式:单例模式的深度剖析
【10月更文挑战第41天】本文深入探讨了Java中广泛使用的单例设计模式,旨在通过简明扼要的语言和实际示例,帮助读者理解其核心原理和应用。文章将介绍单例模式的重要性、实现方式以及在实际应用中如何优雅地处理多线程问题。
32 4
|
2月前
|
设计模式 Java 程序员
[Java]23种设计模式
本文介绍了设计模式的概念及其七大原则,强调了设计模式在提高代码重用性、可读性、可扩展性和可靠性方面的作用。文章还简要概述了23种设计模式,并提供了进一步学习的资源链接。
49 0
[Java]23种设计模式
|
1月前
|
设计模式 JavaScript Java
Java设计模式:建造者模式详解
建造者模式是一种创建型设计模式,通过将复杂对象的构建过程与表示分离,使得相同的构建过程可以创建不同的表示。本文详细介绍了建造者模式的原理、背景、应用场景及实际Demo,帮助读者更好地理解和应用这一模式。
|
2月前
|
设计模式 监控 算法
Java设计模式梳理:行为型模式(策略,观察者等)
本文详细介绍了Java设计模式中的行为型模式,包括策略模式、观察者模式、责任链模式、模板方法模式和状态模式。通过具体示例代码,深入浅出地讲解了每种模式的应用场景与实现方式。例如,策略模式通过定义一系列算法让客户端在运行时选择所需算法;观察者模式则让多个观察者对象同时监听某一个主题对象,实现松耦合的消息传递机制。此外,还探讨了这些模式与实际开发中的联系,帮助读者更好地理解和应用设计模式,提升代码质量。
Java设计模式梳理:行为型模式(策略,观察者等)
|
3月前
|
存储 设计模式 安全
Java设计模式-备忘录模式(23)
Java设计模式-备忘录模式(23)
|
3月前
|
设计模式 存储 算法
Java设计模式-命令模式(16)
Java设计模式-命令模式(16)
|
3月前
|
设计模式 存储 缓存
Java设计模式 - 解释器模式(24)
Java设计模式 - 解释器模式(24)
|
3月前
|
设计模式 安全 Java
Java设计模式-迭代器模式(21)
Java设计模式-迭代器模式(21)
|
3月前
|
设计模式 缓存 监控
Java设计模式-责任链模式(17)
Java设计模式-责任链模式(17)