1. 程式人生 > 程式設計 >淺談JAVA設計模式之享元模式

淺談JAVA設計模式之享元模式

享元模式(Flyweight Pattern)主要用於減少建立物件的數量,以減少記憶體佔用和提高效能。這種型別的設計模式屬於結構型模式,它提供了減少物件數量從而改善應用所需的物件結構的方式。

享元模式嘗試重用現有的同類物件,如果未找到匹配的物件,則建立新物件。我們將通過建立 5 個物件來畫出 20 個分佈於不同位置的圓來演示這種模式。由於只有 5 種可用的顏色,所以 color 屬性被用來檢查現有的 Circle 物件。

介紹

意圖:

運用共享技術有效地支援大量細粒度的物件。

主要解決:

在有大量物件時,有可能會造成記憶體溢位,我們把其中共同的部分抽象出來,如果有相同的業務請求,直接返回在記憶體中已有的物件,避免重新建立。

何時使用:

1、系統中有大量物件。

2、這些物件消耗大量記憶體。

3、這些物件的狀態大部分可以外部化。

4、這些物件可以按照內蘊狀態分為很多組,當把外蘊物件從物件中剔除出來時,每一組物件都可以用一個物件來代替。

5、系統不依賴於這些物件身份,這些物件是不可分辨的。

如何解決:

用唯一標識碼判斷,如果在記憶體中有,則返回這個唯一標識碼所標識的物件。

關鍵程式碼:

用 HashMap 儲存這些物件。

應用例項:

1、JAVA 中的 String,如果有則返回,如果沒有則建立一個字串儲存在字串快取池裡面。

2、資料庫的資料池。

優點:

大大減少物件的建立,降低系統的記憶體,使效率提高。

缺點:

提高了系統的複雜度,需要分離出外部狀態和內部狀態,而且外部狀態具有固有化的性質,不應該隨著內部狀態的變化而變化,否則會造成系統的混亂。

使用場景:

1、系統有大量相似物件。

2、需要緩衝池的場景。

注意事項:

1、注意劃分外部狀態和內部狀態,否則可能會引起執行緒安全問題。

2、這些類必須有一個工廠物件加以控制。

實現

我們將建立一個 Shape 介面和實現了 Shape 介面的實體類 Circle。下一步是定義工廠類 ShapeFactory。

ShapeFactory 有一個 Circle 的 HashMap,其中鍵名為 Circle 物件的顏色。無論何時接收到請求,都會建立一個特定顏色的圓。ShapeFactory 檢查它的 HashMap 中的 circle 物件,如果找到 Circle 物件,則返回該物件,否則將建立一個儲存在 hashmap 中以備後續使用的新物件,並把該物件返回到客戶端。

FlyWeightPatternDemo,我們的演示類使用 ShapeFactory 來獲取 Shape 物件。它將向 ShapeFactory 傳遞資訊(red / green / blue/ black / white),以便獲取它所需物件的顏色。

淺談JAVA設計模式之享元模式

步驟 1

建立一個介面。

public interface Shape {
  void draw();
}

步驟 2

建立實現介面的實體類。

public class Circle implements Shape {
  private String color;
  private int x;
  private int y;
  private int radius;
 
  public Circle(String color){
   this.color = color;   
  }
 
  public void setX(int x) {
   this.x = x;
  }
 
  public void setY(int y) {
   this.y = y;
  }
 
  public void setRadius(int radius) {
   this.radius = radius;
  }
 
  @Override
  public void draw() {
   System.out.println("Circle: Draw() [Color : " + color 
     +",x : " + x +",y :" + y +",radius :" + radius);
  }
}

步驟 3

建立一個工廠,生成基於給定資訊的實體類的物件。

import java.util.HashMap;
 
public class ShapeFactory {
  private static final HashMap<String,Shape> circleMap = new HashMap<>();
 
  public static Shape getCircle(String color) {
   Circle circle = (Circle)circleMap.get(color);
 
   if(circle == null) {
     circle = new Circle(color);
     circleMap.put(color,circle);
     System.out.println("Creating circle of color : " + color);
   }
   return circle;
  }
}

步驟 4

使用該工廠,通過傳遞顏色資訊來獲取實體類的物件。

public class FlyweightPatternDemo {
  private static final String colors[] = 
   { "Red","Green","Blue","White","Black" };
  public static void main(String[] args) {
 
   for(int i=0; i < 20; ++i) {
     Circle circle = 
      (Circle)ShapeFactory.getCircle(getRandomColor());
     circle.setX(getRandomX());
     circle.setY(getRandomY());
     circle.setRadius(100);
     circle.draw();
   }
  }
  private static String getRandomColor() {
   return colors[(int)(Math.random()*colors.length)];
  }
  private static int getRandomX() {
   return (int)(Math.random()*100 );
  }
  private static int getRandomY() {
   return (int)(Math.random()*100);
  }
}

步驟 5

執行程式,輸出結果:

Creating circle of color : Black
Circle: Draw() [Color : Black,x : 36,y :71,radius :100
Creating circle of color : Green
Circle: Draw() [Color : Green,x : 27,y :27,radius :100
Creating circle of color : White
Circle: Draw() [Color : White,x : 64,y :10,radius :100
Creating circle of color : Red
Circle: Draw() [Color : Red,x : 15,y :44,radius :100
Circle: Draw() [Color : Green,x : 19,x : 94,y :32,radius :100
Circle: Draw() [Color : White,x : 69,y :98,radius :100
Creating circle of color : Blue
Circle: Draw() [Color : Blue,x : 13,y :4,x : 21,y :21,radius :100
Circle: Draw() [Color : Blue,x : 55,y :86,x : 90,y :70,x : 78,y :3,y :89,x : 3,y :91,x : 62,y :82,x : 97,y :61,x : 86,y :12,x : 38,y :93,radius :100
Circle: Draw() [Color : Red,x : 76,x : 95,radius :100

以上就是淺談JAVA設計模式之享元模式的詳細內容,更多關於JAVA 享元模式的資料請關注我們其它相關文章!