首页 > 其他分享 >实验

实验

时间:2023-02-11 14:57:58浏览次数:34  
标签:享元 黑子 对象 color 棋子 实验 piece

享元模式 Flyweight Pattern

 

大家都知道围棋有黑白子,用程序定义一局围棋时,如果给每颗黑子和每颗白子都定义一个对象,那一局围棋会产生大量的对象,这样有必要吗?每颗黑子都是类似的,每颗白子也是类似的,完全可以只定义一颗黑子对象和一颗白子对象,其余的棋子都复用这两个对象,这样不仅节省空间,编写也会简单很多,这就是享元模式的思想。

它通过与其他类似对象共享数据来减小内存占用,也就是它名字的来由:享-分享

 

代码实现:

这里以下围棋为例介绍享元模式:

1、定义棋子(抽象享元角色)

/**
* 棋子
*/
public interface Piece {
   /**
    * 落子
    */
   public void fall();
}

2、定义具体棋子(具体享元角色)

/**
* 具体棋子
*/
public class PieceImpl implements Piece{
   /**
    * 棋子
    */
   private String piece;
   /**
    * 构造棋子
    * @param color 棋子颜色
    */
   public PieceImpl(String color) {
       this.piece = color;
  }
   @Override
   public void fall() {
       System.out.println(this.piece);
  }
}

3、定义棋子工厂(享元工厂)

/**
* 棋子工厂
*/
public enum PieceFactory {
   /**
    * 这里将前面介绍的单例模式应用起来<br>
    * 单例模式的最佳实现是使用枚举类型。<br>
    * 只需要编写一个包含单个元素的枚举类型即可<br>
    * 简洁,且无偿提供序列化,并由 JVM 从根本上提供线程安全的保障,绝对防止多次实例化,且能够抵御反射和序列化的攻击。
    */
   INSTANCE;
   /**
    * 棋盒
    */
   private Map<String,Piece> pieceBox = new HashMap<>();
   /**
    * 获取棋子
    * @param color 棋子颜色
    * @return 棋子
    */
   public Piece getPiece(String color) {
       // 先从棋盒获取棋子
       Piece piece = this.pieceBox.get(color);
       // 如果棋盒里没有棋子
       if (piece == null) {
           // 创建一颗棋子
           piece = new PieceImpl(color);
           // 放入棋盒
           this.pieceBox.put(color, piece);
      }
       // 得到棋子
       return piece;
  }
}

4、调用

// 获取棋子1
Piece piece1 = PieceFactory.INSTANCE.getPiece("黑子");
// 获取棋子2
Piece piece2 = PieceFactory.INSTANCE.getPiece("黑子");
// 获取棋子3
Piece piece3 = PieceFactory.INSTANCE.getPiece("白子");
// 落子
piece1.fall();
piece2.fall();
piece3.fall();
// 比较两颗黑子是否为同一对象
System.out.println(piece1 == piece2);
// 比较两颗白子是否为同一对象
System.out.println(piece1 == piece3);

输出结果为:

黑子
黑子
白子
true
false

可以发现,两颗黑子为同一对象,黑子与白子为不同对象,这样不管后面定义多少黑子与白子,都可以公用现存的两个对象,极大程度的节省了内存,这就是享元模式的妙处。

 

与单例模式区别:

可以发现,享元工厂的实现方式与单例模式很相似,都在强调复用对象。但它们还是有本质区别的:

  • 享元对象级别的:在多个使用到这个对象的地方都只需要使用这一个对象即可满足要求。

  • 单例类级别的:这个类必须只能实例化出一个对象。

可以这么说:单例是享元的一种特例。单例可以看做是享元的实现方式中的一种,只不过比享元更加严格的控制了对象的唯一性。

 

优缺点:

优点

大幅度地降低内存中对象的数量,对象数量越多,越能体现得明显。

缺点

1、享元模式使得系统更加复杂。为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑复杂化。

2、享元模式将享元对象的状态外部化,而读取外部状态使得运行时间稍微变长。

3、享元模式需要维护一个记录了系统已有的所有享元的哈希表,也称之为对象池,这也需要耗费一定的资源。

 

使用场景:

足够多的对象可共享时才值得使用享元模式

 

标签:享元,黑子,对象,color,棋子,实验,piece
From: https://www.cnblogs.com/dzwj/p/17111648.html

相关文章