天天看點

結構型模式-07享元模式

文章目錄

    • 七、享元模式
      • 1. `定義`
      • 2. `結構`
      • 3. `案例`
      • 4. `代碼`
      • 5. `優點`
      • 6. `缺點`
      • 7. `使用注意`
      • 8. `JDK源碼(看源碼,裡面用到了享元模式)`

七、享元模式

1.

定義

  • 運用共享技術來有效地支援大量細粒度對象的複用。它通過共享已經存在的對象來大幅度減少需要建立 的對象數量、避免大量相似對象的開銷,進而提高系統資源的使用率。

2.

結構

  • 抽象享元角色:通常是一個接口或抽象類,在抽象享元類中聲明了具體享元類公 共的方法,這些方法可以向外界提供享元對象的内部資料(内部狀态),同時也可以通過這些方法 來設定外部資料(外部狀态)。
  • 具體享元(Concrete Flyweight)角色 :它實作了抽象享元類,稱為享元對象;在具體享元 類中為内部狀态提供了存儲空間。通常我們可以結合單例模式來設計具體享元類,為每一個具體享 元類提供唯一的享元對象。
  • 非享元(Unsharable Flyweight)角色 :并不是所有的抽象享元類的子類都需要被共享,不 能被共享的子類可設計為非共享具體享元類;當需要一個非共享具體享元類的對象時可以直接通過執行個體化建立。
  • 享元工廠(Flyweight Factory)角色 :負責建立和管理享元角色。當客戶對象請求一個享元 對象時,享元工廠檢査系統中是否存在符合要求的享元對象,如果存在則提供給客戶;如果不存在 的話,則建立一個新的享元對象。

3.

案例

  • 不同手機有不同的顔色
  • UML
結構型模式-07享元模式

4.

代碼

  • AbstractPhone
/**
 * 抽象享元角色 : 抽取共有屬性和方法
 */
public abstract class AbstractPhone {
    //擷取手機名字的方法
    public abstract  String getName();

    //顯示手機顔色
    public void show(String color){
        System.out.println("手機名字:"+getName()+",顔色:"+color);
    }
}
           
  • HuaWei類 Iphone、XiaoMi類似
/**
 * HuaWei類--具體享元角色
 */
public class HuaWei extends AbstractPhone{
    @Override
    public String getName() {
        return "Huawei";
    }
}
           
  • PhoneFactory
/**
 * 工廠類,将該類設計為單例 該工廠對象隻需要一個  享元工廠角色
 */
public class PhoneFactory {
    private HashMap<String, AbstractPhone> map;

    //構造方法中初始化操作
    public PhoneFactory() {
        map = new HashMap<>();
        map.put("xiaomi", new XiaoMi());
        map.put("iphone", new Iphone());
        map.put("huawei", new HuaWei());
    }

    //提供外界擷取工廠類的對象,單例中的餓漢式
    public static PhoneFactory getInstance() {
        return factory;
    }

    private static PhoneFactory factory = new PhoneFactory();

    //根據名稱擷取手機對象
    public AbstractPhone getName(String name) {
        return map.get(name);
    }
}
           
  • 測試類
public class Client {
    public static void main(String[] args) {
        AbstractPhone phone1 = PhoneFactory.getInstance().getName("xiaomi");
        phone1.show("黑金");

        AbstractPhone phone2 = PhoneFactory.getInstance().getName("huawei");
        phone2.show("粉色");

        AbstractPhone phone3 = PhoneFactory.getInstance().getName("iphone");
        phone3.show("天藍");

        AbstractPhone phone4 = PhoneFactory.getInstance().getName("xiaomi");
        phone4.show("白色");

        System.out.println(phone1 == phone4);
    }
}
           
  • 測試結果
手機名字:xiaomi,顔色:黑金
手機名字:Huawei,顔色:粉色
手機名字:iphone,顔色:天藍
手機名字:xiaomi,顔色:白色
true
           

5.

優點

  1. 減少記憶體中相似或相同對象的數量,節約系統資源
  2. 享元模式中的外部狀态相對獨立,且不影響内部狀态

6.

缺點

  • 為了使對象可以共享,需要将享元對象的部分狀态外部化,分離内部狀态和外部狀态,使程式邏輯複雜

7.

使用注意

  • 需要多次重複使用享元對象時才址得使用享元模式

8.

JDK源碼(看源碼,裡面用到了享元模式)

public class Demo {
        public static void main(String[] args) {
            Integer i1 = 127;
            Integer i2 = 127;
            System.out.println(i1 == i2);
            Integer i3 = 128;
            Integer i4 = 128;
            System.out.println(i3 == i4);
        }
    }
//true
//false