目录
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;
@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;
// 可以添加其他需要重置的字段或状态
}
}
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.示例截图