天天看點

Java單體應用 - 架構模式 - 03.設計模式-12.享元模式享元模式

原文位址: http://www.work100.net/training/monolithic-architecture-design-patterns-flyweight-pattern.html 更多教程: 光束雲 - 免費課程

享元模式

序号 文内章節 視訊
1 概述 -
2 實作

請參照如上

章節導航

進行閱讀

1.概述

享元模式(

Flyweight Pattern

)主要用于減少建立對象的數量,以減少記憶體占用和提高性能。這種類型的設計模式屬于結構型模式,它提供了減少對象數量進而改善應用所需的對象結構的方式。

享元模式嘗試重用現有的同類對象,如果未找到比對的對象,則建立新對象。

我們将通過建立

5

個對象來畫出

20

個分布于不同位置的圓來示範這種模式。由于隻有

5

種可用的顔色,是以

color

屬性被用來檢查現有的

Circle

對象。

意圖:

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

主要解決:

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

何時使用:

  • 系統中有大量對象。
  • 這些對象消耗大量記憶體。
  • 這些對象的狀态大部分可以外部化。
  • 這些對象可以按照内蘊狀态分為很多組,當把外蘊對象從對象中剔除出來時,每一組對象都可以用一個對象來代替。
  • 系統不依賴于這些對象身份,這些對象是不可分辨的。

如何解決:

用唯一辨別碼判斷,如果在記憶體中有,則傳回這個唯一辨別碼所辨別的對象。

關鍵代碼:

HashMap

存儲這些對象。

應用執行個體:

  • Java 中的

    String

    ,如果有則傳回,如果沒有則建立一個字元串儲存在字元串緩存池裡面。
  • 資料庫的資料池。

優點:

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

缺點:

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

使用場景:

  • 系統有大量相似對象。
  • 需要緩沖池的場景。

注意事項:

  • 注意劃分外部狀态和内部狀态,否則可能會引起線程安全問題。
  • 這些類必須有一個工廠對象加以控制。

2.實作

我們将建立一個

Shape

接口和實作了

Shape

接口的實體類

Circle

。下一步是定義工廠類

ShapeFactory

ShapeFactory

有一個

Circle

HashMap

,其中鍵名為

Circle

對象的顔色。

無論何時接收到請求,都會建立一個特定顔色的圓。

ShapeFactory

檢查它的

HashMap

中的

circle

對象,如果找到

Circle

對象,則傳回該對象,否則将建立一個存儲在

hashmap

中以備後續使用的新對象,并把該對象傳回到用戶端。

FlyWeightPatternDemo

,我們的示範類使用

ShapeFactory

來擷取

Shape

它将向

ShapeFactory

傳遞資訊(

red

/

green

blue

black

white

),以便擷取它所需對象的顔色。

步驟 1

建立一個接口。

Shape.java

,代碼如下:

public interface Shape {
   void draw();
}           

步驟 2

建立實作接口的實體類。

Circle.java

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

建立一個工廠,生成基于給定資訊的實體類的對象。

ShapeFactory.java

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

使用該工廠,通過傳遞顔色資訊來擷取實體類的對象。

FlyweightPatternDemo.java

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, y :10, radius :100
Circle: Draw() [Color : Green, 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, radius :100
Circle: Draw() [Color : Green, x : 21, y :21, radius :100
Circle: Draw() [Color : Blue, x : 55, y :86, radius :100
Circle: Draw() [Color : White, x : 90, y :70, radius :100
Circle: Draw() [Color : Green, x : 78, y :3, radius :100
Circle: Draw() [Color : Green, x : 64, y :89, radius :100
Circle: Draw() [Color : Blue, x : 3, y :91, radius :100
Circle: Draw() [Color : Blue, x : 62, y :82, radius :100
Circle: Draw() [Color : Green, x : 97, y :61, radius :100
Circle: Draw() [Color : Green, x : 86, y :12, radius :100
Circle: Draw() [Color : Green, x : 38, y :93, radius :100
Circle: Draw() [Color : Red, x : 76, y :82, radius :100
Circle: Draw() [Color : Blue, x : 95, y :82, radius :100           

上一篇:

外觀模式

下一篇:

代理模式
如果對課程内容感興趣,可以掃碼關注我們的

公衆号

QQ群

,及時關注我們的課程更新
Java單體應用 - 架構模式 - 03.設計模式-12.享元模式享元模式
Java單體應用 - 架構模式 - 03.設計模式-12.享元模式享元模式