目录 1. 说明 2. 应用场景 3. 结构图 4. 构成 5. 适用性 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示例
package com.learning.flyweight.bullet;/*** 子弹的抽象享元类*/
public interface Bullet {/*** 开火*/void fire();/*** 设置子弹位置* @param x* @param y*/void setPosition(int x, int y);/*** 重置子弹*/void reset();
}
package com.learning.flyweight.bullet;// 具体的子弹享元类
public class BulletImpl implements Bullet {private int x;private int y;@Overridepublic void fire() {System.out.println("Bullet fired at position (" + x + ", " + y + ")");}@Overridepublic void setPosition(int x, int y) {this.x = x;this.y = y;}@Overridepublic void reset() {// 在这里重置子弹的状态,例如将其位置设置为默认值this.x = 0;this.y = 0;// 可以添加其他需要重置的字段或状态}
}
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); // 将子弹添加到池中以便将来重用}
}
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.示例截图