Java享元模式(FlyWeight)

简介: 内存属于稀缺资源,不要随便浪费。如果有很多个完全相同或相似的对象,我们可以通过享元模式,节省内存.


享元模式

 内存属于稀缺资源,不要随便浪费。如果有很多个完全相同或相似的

对象,我们可以通过享元模式,节省内存.

核心:

   享元模式以共享的方式高效地支持大量细粒度对象的重用。

   享元对象能做到共享的关键是区分了内部状态和外部状态。

   • 内部状态:可以共享,不会随环境变化而改变

   • 外部状态:不可以共享,会随环境变化而改变

案例

围棋软件设计

每个围棋棋子都是一个对象,

有如下属性:

image.pngimage.png

享元模式实现:

   FlyweightFactory享元工厂类

   • 创建并管理享元对象,享元池一般设计成键值对

   FlyWeight抽象享元类

   • 通常是一个接口或抽象类,声明公共方法,这些方法可以向外界提供对象

   的内部状态,设置外部状态。

   ConcreteFlyWeight具体享元类

   • 为内部状态提供成员变量进行存储

   UnsharedConcreteFlyWeight非共享享元类

   • 不能被共享的子类可以设计为非共享享元类

享元模式实现的UML图

image.png

实现代码

享元类

/**
 * 享元类
 * @author 波波烤鸭
 * @email dengpbs@163.com
 *
 */
public interface ChessFlyWeight {
  void setColor(String c);
  String getColor();
  void display(Coordinate c);
}
/**
 * 棋子 具体实现类
 * @author 波波烤鸭
 * @email dengpbs@163.com
 *
 */
class ConcreteChess implements ChessFlyWeight {
  private String color;
  public ConcreteChess(String color) {
    super();
    this.color = color;
  }
  @Override
  public void display(Coordinate c) {
    System.out.println("棋子颜色:"+color);
    System.out.println("棋子位置:"+c.getX()+"----"+c.getY());
  }
  @Override
  public String getColor() {
    return color;
  }
  @Override
  public void setColor(String c) {
    this.color = c;
  }
}

外部状态

/**
 * 外部状态UnSharedConcreteFlyWeight
 * @author 波波烤鸭
 * @email dengpbs@163.com
 *
 */
public class Coordinate {
  private int x,y;
  public Coordinate(int x, int y) {
    super();
    this.x = x;
    this.y = y;
  }
  public int getX() {
    return x;
  }
  public void setX(int x) {
    this.x = x;
  }
  public int getY() {
    return y;
  }
  public void setY(int y) {
    this.y = y;
  }
}

享元工厂类

/**
 *享元工厂类
 *    创建棋子
 * @author 波波烤鸭
 * @email dengpbs@163.com
 *
 */
public class ChessFlyWeightFactory {
  //享元池  根据颜色保存不同的棋子对象
  private static Map<String,ChessFlyWeight> map = new HashMap<String, ChessFlyWeight>();
  public static ChessFlyWeight  getChess(String color){
    // 如果已经存在该颜色的棋子返回
    if(map.get(color)!=null){
      return map.get(color);
    }else{
      // 如果享元池中没有该颜色的棋子就创建一个新的返回 并存储在享元池中
      ChessFlyWeight cfw = new ConcreteChess(color);
      map.put(color, cfw);
      return cfw;
    }
  } 
}

测试类

public class Client {
  public static void main(String[] args) {
    ChessFlyWeight chess1 = ChessFlyWeightFactory.getChess("黑色");
    ChessFlyWeight chess2 = ChessFlyWeightFactory.getChess("黑色");
    ChessFlyWeight chess3 = ChessFlyWeightFactory.getChess("白色");
    System.out.println(chess1);
    System.out.println(chess2);
    System.out.println(chess3);
    System.out.println("增加外部状态的处理===========");
    chess1.display(new Coordinate(10, 10));
    chess2.display(new Coordinate(20, 20));
  }
}

输出结果:

com.bjsxt.flyweight.ConcreteChess@15db9742
com.bjsxt.flyweight.ConcreteChess@15db9742
com.bjsxt.flyweight.ConcreteChess@6d06d69c
增加外部状态的处理===========
棋子颜色:黑色
棋子位置:10----10
棋子颜色:黑色
棋子位置:20----20

享元模式开发中应用的场景:

 享元模式由于其共享的特性,可以在任何“池”中操作,比如:线程池、数据库连接池。 String类的设计也是享元模式

优点

   极大减少内存中对象的数量

   相同或相似对象内存中只存一份,极大的节约资源,提高系统性能

   外部状态相对独立,不影响内部状态

缺点

   模式较复杂,使程序逻辑复杂化

   为了节省内存,共享了内部状态,分离出外部状态,而读取外部状态

   使运行时间变长。用时间换取了空间。


相关文章
|
9月前
|
设计模式 缓存 安全
【高薪程序员必看】万字长文拆解Java并发编程!(8):设计模式-享元模式设计指南
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发编程中的经典对象复用设计模式-享元模式,废话不多说让我们直接开始。
200 0
|
设计模式 Java
Java设计模式-享元模式(12)
Java设计模式-享元模式(12)
188 1
|
设计模式 存储 Java
【十】设计模式~~~结构型模式~~~享元模式(Java)
文章详细介绍了享元模式(Flyweight Pattern),这是一种对象结构型模式,通过共享技术实现大量细粒度对象的重用,区分内部状态和外部状态来减少内存中对象的数量,提高系统性能。通过围棋棋子的设计案例,展示了享元模式的动机、定义、结构、优点、缺点以及适用场景,并探讨了单纯享元模式和复合享元模式以及与其他模式的联用。
【十】设计模式~~~结构型模式~~~享元模式(Java)
|
设计模式 缓存 Java
Java设计模式:享元模式实现高效对象共享与内存优化(十一)
Java设计模式:享元模式实现高效对象共享与内存优化(十一)
|
设计模式 存储 Java
Java设计模式之享元模式详解
Java设计模式之享元模式详解
|
设计模式 存储 Java
[设计模式Java实现附plantuml源码~结构型]实现对象的复用——享元模式
[设计模式Java实现附plantuml源码~结构型]实现对象的复用——享元模式
171 0
|
设计模式 存储 Java
23种设计模式,享元模式的概念优缺点以及JAVA代码举例
【4月更文挑战第6天】享元模式(Flyweight Pattern)是一种结构型设计模式,旨在通过共享技术有效地支持大量细粒度对象的重用。这个模式在处理大量对象时非常有用,特别是当这些对象中的许多实例实际上可以共享相同的状态时,从而可以减少内存占用,提高程序效率
264 4
|
设计模式 存储 缓存
聊聊Java设计模式-享元模式
享元(Flyweight)模式:顾名思义就是**被共享的单元**。意图是复用对象,节省内存,提升系统的访问效率。比如在红白机冒险岛游戏中的背景花、草、树木等对象,实际上是可以多次被不同场景所复用共享,也是为什么以前的游戏占用那么小的内存,却让我们感觉地图很大的原因。
201 3
聊聊Java设计模式-享元模式
|
存储 设计模式 缓存
享元模式 rust和java的实现
享元模式 rust和java的实现
154 0
|
设计模式 缓存 Java
JAVA设计模式12:享元模式,避免创建大量相似对象的开销
JAVA设计模式12:享元模式,避免创建大量相似对象的开销
183 0