Java設(shè)計模式之-享元模式
什么是享元模式?
享元模式是一種設(shè)計模式,用于減少對象的內(nèi)存占用和提高性能。它通過共享相似對象的內(nèi)部狀態(tài)來減少重復(fù)對象的創(chuàng)建。
主要解決什么問題?
享元模式主要解決兩個問題:
大量相似對象的內(nèi)存占用:當系統(tǒng)中存在大量相似的對象時,每個對象都會占用一定的內(nèi)存空間,導(dǎo)致內(nèi)存消耗過大。
對象的創(chuàng)建和銷毀開銷:頻繁創(chuàng)建和銷毀對象會帶來一定的開銷,影響系統(tǒng)性能。
在什么時候我們需要使用享元模式?
當滿足以下條件時,可以考慮使用享元模式:
系統(tǒng)中存在大量相似的對象,且這些對象的區(qū)別可以拆分為內(nèi)部狀態(tài)和外部狀態(tài)。
對象的創(chuàng)建和銷毀頻率較高,需要減少對象的內(nèi)存占用和創(chuàng)建銷毀開銷。
用一個生活中的應(yīng)用實例來舉例、類比
假設(shè)你正在開發(fā)一個電子商務(wù)網(wǎng)站,你需要展示大量的產(chǎn)品信息。每個產(chǎn)品都有一些共同的屬性,比如名稱、價格和庫存數(shù)量,以及一些不同的屬性,比如顏色和尺寸。這里,產(chǎn)品可以被看作是享元對象。
使用享元模式,你可以將共同屬性作為內(nèi)部狀態(tài),而將不同的屬性作為外部狀態(tài)。當展示產(chǎn)品時,可以共享相同內(nèi)部狀態(tài)的產(chǎn)品對象,并根據(jù)不同的外部狀態(tài)設(shè)置其屬性值。通過共享對象,可以減少內(nèi)存占用,避免創(chuàng)建大量相似的產(chǎn)品對象。
優(yōu)點
享元模式的優(yōu)點包括:
減少內(nèi)存占用:通過共享相似對象的內(nèi)部狀態(tài),減少內(nèi)存占用。
提高性能:共享對象的復(fù)用減少了對象的創(chuàng)建和銷毀開銷,提高了系統(tǒng)性能。
缺點
享元模式的缺點包括:
引入共享對象管理:引入共享對象需要額外的管理機制,增加了系統(tǒng)的復(fù)雜性。
對象狀態(tài)共享:共享對象的內(nèi)部狀態(tài)需要是可共享的,如果對象有可變狀態(tài),則需要進行額外的處理。
使用場景
享元模式適用于以下情況:
系統(tǒng)中存在大量相似的對象,且這些對象的區(qū)別可以拆分為內(nèi)部狀態(tài)和外部狀態(tài)。
對象的創(chuàng)建和銷毀頻率較高,需要減少對象的內(nèi)存占用和創(chuàng)建銷毀開銷。
下面是一個簡單的Java代碼示例:
import java.util.HashMap;
import java.util.Map;
// 享元接口
interface Product {
? ? void display(String color);
}
// 具體享元類
class ConcreteProduct implements Product {
? ? private String name;
? ? public ConcreteProduct(String name) {
? ? ? ? this.name = name;
? ? }
? ? public void display(String color) {
? ? ? ? System.out.println("Displaying " + name + " in " + color);
? ? }
}
// 享元工廠類
class ProductFactory {
? ? private Map<String, Product> productMap;
? ? public ProductFactory() {
? ? ? ? productMap = new HashMap<>();
? ? }
? ? public Product getProduct(String name) {
? ? ? ? Product product = productMap.get(name);
? ? ? ? if (product == null) {
? ? ? ? ? ? product = new ConcreteProduct(name);
? ? ? ? ? ? productMap.put(name, product);
? ? ? ? }
? ? ? ? return product;
? ? }
}
// 客戶端
public class Client {
? ? public static void main(String[] args) {
? ? ? ? ProductFactory productFactory = new ProductFactory();
? ? ? ? Product product1 = productFactory.getProduct("Product A");
? ? ? ? product1.display("Red");
? ? ? ? Product product2 =productFactory.getProduct("Product A");
? ? ? ? product2.display("Blue");
? ? ? ? Product product3 = productFactory.getProduct("Product B");
? ? ? ? product3.display("Green");
? ? }
}
在這個示例中,Product 接口定義了 display 方法,表示產(chǎn)品的展示。ConcreteProduct 是具體的享元類,實現(xiàn)了 Product 接口,并包含一個內(nèi)部狀態(tài) name 。ProductFactory 是享元工廠類,負責(zé)創(chuàng)建和管理產(chǎn)品對象。在客戶端代碼中,通過工廠類獲取產(chǎn)品對象,并調(diào)用 display 方法展示產(chǎn)品。
通過使用享元模式,當獲取相同名稱的產(chǎn)品時,只會創(chuàng)建一個對象并進行共享,從而減少了內(nèi)存占用和對象的創(chuàng)建開銷。