目录
-
-
-
- [1. 说明](#1. 说明)
- [2. 应用场景](#2. 应用场景)
- [3. 结构图](#3. 结构图)
- [4. 构成](#4. 构成)
- [5. 适用性](#5. 适用性)
- [6. java示例](#6. java示例)
-
-
1. 说明
- 1.享元设计模式(Flyweight Design Pattern)是一种常见的软件设计模式
- 2.属于结构型设计模式,对象结构型模式
- 3.目的:运用共享技术有效地支持大量细粒度的对象
2. 应用场景
- 1.类的结构改变较少,但经常要增加新的基于该结构的操作
- 2.需要对某一对象结构的对象进行很多不同的并且不相关的操作,而需要避免让这些操作污染这些对象的类,也不希望在新增操作时修改这些类
3. 结构图
4. 构成
- 1.享元模式的结构主要包含一下三个角色:抽象享元(Flyweight)角色、具体享元(Concrete Flyweight)角色和享元工厂(Flyweight Factory)角色
- 2.抽象享元(Flyweight)角色:通常是一个接口或抽象类,在其中声明了具体享元类公共的方法。这些方法可以向外界提供享元对象的内部数据(内部状态),同时也可以设置外部数据(外部状态)。抽象享元角色规定了享元对象的统一接口,使得客户端可以透明地使用具体享元对象。
- 3.具体享元(Concrete Flyweight)角色:实现了抽象享元类,为其内部状态提供了存储空间。通常,可以结合单例模式来设计具体享元类,为每个具体享元类提供唯一的对象。具体享元对象是可以共享的,它们存储了不会随环境改变而改变的可共享状态。
- 4.享元工厂(Flyweight Factory)角色:负责创建和管理享元对象。当客户端请求一个享元对象时,享元工厂会检查是否已经存在具有相同内部状态的对象。如果存在,就返回已经存在的对象;如果不存在,就创建一个新的具体享元对象。享元工厂通常提供一个存储享元对象的享元池,用于缓存已经创建的享元对象。
- 5.并非所有的Flyweight子类都需要被共享。Flyweight接口使共享成为可能,但它并不强制共享。在Flyweight对象结构的某些层次,UnsharedConcreteFlyweight对象通常将ConcreteFlyweight对象作为子结点
- 6.Client 维持一个对 Flyweight 的引用;计算或存储一个或多个 Flyweight 的外部状态。
5. 适用性
- 1.一个应用程序使用了大量的对象
- 2.完全由于使用大量的对象,造成很大的存储开销
- 3.对象的大多数状态都可变为外部状态
- 4.如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象
- 5.应用程序不依赖于对象标识。由于Flyweight对象可以被共享,所以对于概念上明显有别的对象,标识测试将返回真值
6. java示例
-
1.抽象享元角色声明了具体享元类公共的方法
package com.learning.flyweight.bullet;
/**
-
子弹的抽象享元类
/
public interface Bullet {
/*- 开火
*/
void fire();
/**
- 设置子弹位置
- @param x
- @param y
*/
void setPosition(int x, int y);
/**
- 重置子弹
*/
void reset();
}
- 开火
-
-
2.具体享元角色
package com.learning.flyweight.bullet;
// 具体的子弹享元类
public class BulletImpl implements Bullet {
private int x;
private int y;@Override public void fire() { System.out.println("Bullet fired at position (" + x + ", " + y + ")"); } @Override public void setPosition(int x, int y) { this.x = x; this.y = y; } @Override public void reset() { // 在这里重置子弹的状态,例如将其位置设置为默认值 this.x = 0; this.y = 0; // 可以添加其他需要重置的字段或状态 }
}
-
3.享元工厂角色
package com.learning.flyweight.bullet;
import java.util.ArrayList;
import java.util.List;// 子弹工厂(享元工厂)
class BulletFactory {
private List<Bullet> list = new ArrayList<>();// 获取子弹对象 public Bullet getBullet() { if (!list.isEmpty()) { // 如果有可用的子弹(即已经回收的子弹),则重用 Bullet bullet = list.remove(list.size() - 1); bullet.reset(); // 重置子弹状态 return bullet; } else { // 如果没有可用的子弹,则创建一个新的子弹 return new BulletImpl(); } } // 回收子弹对象 public void recycleBullet(Bullet bullet) { list.add(bullet); // 将子弹添加到池中以便将来重用 }
}
-
4.客户端
package com.learning.flyweight.bullet;
public class Client {
public static void main(String[] args) { BulletFactory bulletFactory = new BulletFactory(); Bullet bullet = bulletFactory.getBullet(); bullet.setPosition(100, 200); bullet.fire(); // 一段时间后回收子弹(这里假设子弹在发射后立即回收) bulletFactory.recycleBullet(bullet); bullet = bulletFactory.getBullet(); bullet.setPosition(50, 250); bullet.fire(); // 一段时间后回收子弹(这里假设子弹在发射后立即回收) bulletFactory.recycleBullet(bullet); }
}
-
5.示例截图