国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【享元設(shè)計模式詳解】C/Java/JS/Go/Python/TS不同語言實現(xiàn)

這篇具有很好參考價值的文章主要介紹了【享元設(shè)計模式詳解】C/Java/JS/Go/Python/TS不同語言實現(xiàn)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

簡介

享元模式(Flyweight Pattern),是一種結(jié)構(gòu)型設(shè)計模式。主要用于減少創(chuàng)建對象的數(shù)量,以減少內(nèi)存占用和提高性能。它摒棄了在每個對象中保存所有數(shù)據(jù)的方式,通過共享多個對象所共有的相同狀態(tài),讓你能在有限的內(nèi)存容量中載入更多對象。

當(dāng)程序需要生成數(shù)量巨大的相似對象時,可能對內(nèi)存有大量損耗,而對象中包含可抽取且能在多個對象間共享的重復(fù)狀態(tài),您可以采取享元模式。

內(nèi)部狀態(tài) vs. 外部狀態(tài)
內(nèi)部狀態(tài)是存儲在享元對象內(nèi)部,一般在構(gòu)造時確定或通過setter設(shè)置,并且不會隨環(huán)境改變而改變的狀態(tài),因此內(nèi)部狀態(tài)可以共享。
外部狀態(tài)是隨環(huán)境改變而改變、不可以共享的狀態(tài)。外部狀態(tài)在需要使用時通過客戶端傳入享元對象。外部狀態(tài)必須由客戶端保存。

?

作用

  1. 有相同的業(yè)務(wù)請求,直接返回在內(nèi)存中已有的對象,避免重新創(chuàng)建。
  2. 如果程序中有很多相似對象,可減少對象的創(chuàng)建,降低系統(tǒng)的內(nèi)存,使效率提高。

?

實現(xiàn)步驟

  1. 創(chuàng)建享元角色抽象接口,用于具體享元角色實現(xiàn)。
  2. 創(chuàng)建具體享元角色,實現(xiàn)抽象方法。具體享元角色就是一般類,該類可以支持外部狀態(tài)數(shù)據(jù)。
  3. 創(chuàng)建享元工廠,里面建一個儲存對象共享池,對已經(jīng)實例化的對象直接取出返回。

?

UML

【享元設(shè)計模式詳解】C/Java/JS/Go/Python/TS不同語言實現(xiàn)

?

?

Java代碼

?

享元抽象接口

 

// Flyweight.java 享元角色抽象接口
public interface Flyweight {
   void operate(String state);
}

?

?

具體享元角色

?

// ConcreteFlyweight.java 具體享元角色,實現(xiàn)抽象接口,用于共享狀態(tài),一個類被創(chuàng)建以后就不用重復(fù)創(chuàng)建了
public class ConcreteFlyweight implements Flyweight {
   private String name;
   private String type;

   public ConcreteFlyweight(String name) {
      // 內(nèi)部狀態(tài),即不會隨著環(huán)境的改變而改變的可共享部分
      // 這里的name也是對象保存的key
      this.name = name;
      this.type = "piano";
      System.out.println("ConcreteFlyweight::ConcreteFlyweight(name) [創(chuàng)建具體享元" + name + "]");
   }

  // 這里state屬于外部狀態(tài),由外部調(diào)用時傳入
  // 也可以把非共享的對象傳入進來
   @Override
   public void operate(String state) {
      System.out.println(
            String.format("%s::operate() [%s %s %s]", this.getClass().getName(), this.getName(),
                  this.getType(), state));
   }

   public String getName() {
      return this.name;
   }

   public String getType() {
      return this.type;
   }
}

?

?

// UnsharedConcreteFlyweight.java 無需共享的角色,每次都是新實例
public class UnsharedConcreteFlyweight implements Flyweight {
   private String name;
   private String type = "guitar";

   public UnsharedConcreteFlyweight(String name) {
      this.name = name;
      System.out.println("UnsharedConcreteFlyweight::UnsharedConcreteFlyweight(name) [創(chuàng)建非共享對象" + name + "]");
   }


   // 這里state屬于外部狀態(tài),在調(diào)用時外部傳入。
   @Override
   public void operate(String state) {
      System.out.println(
            String.format("%s::operate() [%s %s %s]", this.getClass().getName(), this.getName(),
                  this.getType(), state));
   }

   public String getName() {
      return this.name;
   }

   public String getType() {
      return this.type;
   }
}

?

?

享元工廠類

?

// FlyweightFactory.java 享元工廠,儲存一個對象共享池,已經(jīng)生成過的對象直接取出
public class FlyweightFactory {
   public static Map<String, Flyweight> pool = new HashMap<String, Flyweight>();

   // 這里的name可以認為是內(nèi)部狀態(tài),在構(gòu)造時確定,具有唯一性。
   public static Flyweight getFactory(String name) {
      Flyweight flyweight = pool.get(name);
      if (flyweight == null) {
         // 如果對象不存在則創(chuàng)建新的對象放入到池子里,如果已經(jīng)存在則復(fù)用前面的對象
         flyweight = new ConcreteFlyweight(name);
         pool.put(name, flyweight);
      } else {
         System.out.println("FlyweightFactory::getFactory(name) [成功獲取具體享元" + name + "]");
       }
      return flyweight;
   }
}
 

?

測試調(diào)用

?

    /**
     * 享元模式就是將已經(jīng)聲明過的實例或數(shù)據(jù)保存在內(nèi)存里,需要使用時則取出來,無需再次實例化和聲明。
     * 通過共享多個對象所共有的相同狀態(tài),以達到節(jié)省開銷的目的。
     * 享元模式分為內(nèi)部狀態(tài)和外部狀態(tài),內(nèi)部狀態(tài)基于享元對象共享,外部狀態(tài)則外部傳入或使用非享元類。
     */

    // 假設(shè)有鋼琴和吉他,鋼琴使用者很多需要共享實例,而吉他每次創(chuàng)建新實例

    // 2個一樣名稱的為共享對象,只創(chuàng)建1個實例,后面的返回緩存實例
    Flyweight factory1 = FlyweightFactory.getFactory("piano1");
    // piano1已經(jīng)聲明過了,同名則共享前面的實例
    Flyweight factory2 = FlyweightFactory.getFactory("piano1");
    Flyweight factory3 = FlyweightFactory.getFactory("piano2");
    Flyweight factory4 = FlyweightFactory.getFactory("piano2");

    factory1.operate("factory1");
    factory2.operate("factory2");
    factory3.operate("factory3");
    factory4.operate("factory4");

    // 查看一共多少個對象
    for (Map.Entry<String, Flyweight> entry : FlyweightFactory.pool.entrySet()) {
      System.out.println("享元對象:" + entry.getKey());
      // entry.getValue().operate(null);
    }

    // 無需共享的,名字一樣也是多個對象
    Flyweight factory5 = new UnsharedConcreteFlyweight("guitar1");
    Flyweight factory6 = new UnsharedConcreteFlyweight("guitar1");
    factory5.operate("factory5");
    factory6.operate("factory6");
 

?

C代碼

?

頭文件

?

// func.h 公共頭文件
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

// 享元角色抽象接口
typedef struct Flyweight
{
    char name[50];
    char kind[50];
    void (*operate)(struct Flyweight *, char *);
} Flyweight;

// 享元工廠,儲存一個對象共享池,已經(jīng)生成過的對象直接取出
typedef struct FlyweightFactory
{
    char name[50];
    int (*get_pool_size)();
    Flyweight **(*get_pool)();
    Flyweight *(*get_factory)(char *name);
} FlyweightFactory;
FlyweightFactory *flyweight_factory_constructor(char *name);

// 具體享元角色,實現(xiàn)抽象接口,用于共享狀態(tài),一個類被創(chuàng)建以后就不用重復(fù)創(chuàng)建了
typedef struct ConcreteFlyweight
{
    // 內(nèi)部狀態(tài),即不會隨著環(huán)境的改變而改變的可共享部分
    // 這里的name也是對象保存的key
    char name[50];
    char kind[50];
    void (*operate)(struct ConcreteFlyweight *, char *);
} ConcreteFlyweight;
ConcreteFlyweight *concrete_flyweight_constructor(char *name);
ConcreteFlyweight *concrete_flyweight_init(char *name);

// 無需共享實例的角色,用于處理外部非共享狀態(tài)
// 當(dāng)不需要共享時用這樣的類
typedef struct UnsharedConcreteFlyweight
{
    char name[50];
    char kind[50];
    void (*operate)(struct UnsharedConcreteFlyweight *, char *);
} UnsharedConcreteFlyweight;
UnsharedConcreteFlyweight *unshared_concrete_flyweight_constructor(char *name);
UnsharedConcreteFlyweight *unshared_concrete_flyweight_init(char *name);
 

?

享元抽象接口

?

// flyweight.c 享元角色抽象接口
#include "func.h"

// 享元角色抽象基礎(chǔ)struct,相關(guān)定義在head
 

?

具體享元角色

?

// concrete_flyweight.c 具體享元角色,實現(xiàn)抽象接口,用于共享狀態(tài),一個類被創(chuàng)建以后就不用重復(fù)創(chuàng)建了
#include "func.h"

/* 具體享元角色,實現(xiàn)抽象接口,用于共享狀態(tài),一個類被創(chuàng)建以后就不用重復(fù)創(chuàng)建了 */

// 享元對象實例化函數(shù),對象實例化后共享對象
// state屬于外部狀態(tài),由外部調(diào)用時傳入,也可以把非共享的對象傳入進來
void concrete_flyweight_operate(ConcreteFlyweight *flyweight, char *state)
{
  printf("\r\n ConcreteFlyweight::operate() [name=%s kind=%s state=%s]", flyweight->name, flyweight->kind, state);
}

ConcreteFlyweight *concrete_flyweight_constructor(char *name)
{
  printf("\r\n ConcreteFlyweight::concrete_flyweight_constructor() 創(chuàng)建具體享元對象[name=%s]", name);
  Flyweight *flyweight = (Flyweight *)malloc(sizeof(Flyweight));
  strncpy(flyweight->name, name, 50);
  strncpy(flyweight->kind, "piano", 50);
  ConcreteFlyweight *concrete_flyweight = (ConcreteFlyweight *)flyweight;
  concrete_flyweight->operate = &concrete_flyweight_operate;
  return concrete_flyweight;
}
 

?

// unshared_concrete_flyweight.c 無需共享的角色,每次都是新實例
#include "func.h"

/* 無需共享實例的角色,用于處理外部非共享狀態(tài) */

// 非共享對象的外部狀態(tài),這里state屬于外部狀態(tài),在調(diào)用時外部傳入。
void unshared_flyweight_operate(UnsharedConcreteFlyweight *flyweight, char *state)
{
  printf("\r\n UnsharedConcreteFlyweight::operate() [name=%s kind=%s state=%s]", flyweight->name, flyweight->kind, state);
}

// 無需共享的角色,每次都是新實例
UnsharedConcreteFlyweight *unshared_concrete_flyweight_constructor(char *name)
{
  printf("\r\n UnsharedConcreteFlyweight::unshared_concrete_flyweight_constructor() 創(chuàng)建非共享對象[name=%s]", name);
  Flyweight *flyweight = (Flyweight *)malloc(sizeof(Flyweight));
  strncpy(flyweight->name, name, 50);
  strncpy(flyweight->kind, "guitar", 50);
  UnsharedConcreteFlyweight *unshared_flyweight = (UnsharedConcreteFlyweight *)flyweight;
  unshared_flyweight->operate = &unshared_flyweight_operate;
  return unshared_flyweight;
}
 

?

享元工廠類

?

// flyweight_factory.c 享元工廠,儲存一個對象共享池,已經(jīng)生成過的對象直接取出
#include "func.h"

/* 享元工廠,儲存一個對象共享池,已經(jīng)生成過的對象直接取出 */

// 全局用來記錄Flyweight的對象數(shù)組
static Flyweight **flyweight_factory_member_pool;
// 全局用來記錄Flyweight的名稱數(shù)組
static char **flyweight_factory_name_pool;
// 全局記錄flyweight_factory的數(shù)量
static int flyweight_factory_pool_size = 0;

// 這里的name可以認為是內(nèi)部狀態(tài),在構(gòu)造時確定,具有唯一性。
Flyweight *get_factory(char *name)
{

  // 定義公共map用作共享池子,全局共用
  if (flyweight_factory_member_pool == NULL)
  {
    flyweight_factory_member_pool = (Flyweight **)calloc(100, sizeof(Flyweight));
  }
  if (flyweight_factory_name_pool == NULL)
  {
    flyweight_factory_name_pool = (char **)calloc(100, sizeof(char));
  }

  Flyweight **flyweight_pool = flyweight_factory_member_pool;
  char **name_pool = flyweight_factory_name_pool;
  int length = flyweight_factory_pool_size;

  int flyweight_index = -1;
  for (int i = 0; i < length; i++)
  {
    if (name == name_pool[i])
    {
      flyweight_index = i;
      break;
    }
  }

  Flyweight *flyweight;

  // 如果已經(jīng)存在則復(fù)用前面的對象
  if (flyweight_index >= 0)
  {
    flyweight = flyweight_pool[flyweight_index];
    printf("\r\n FlyweightFactory::get_factory() 成功獲取具體享元[name=%s]", name);
  }
  else
  {
    // 不存在則創(chuàng)建新的對象放入到池子里
    flyweight = (Flyweight *)concrete_flyweight_constructor(name);
    flyweight_pool[length] = flyweight;
    name_pool[length] = name;
    flyweight_factory_pool_size += 1;
    printf("\r\n FlyweightFactory::get_factory() 成功創(chuàng)建具體享元[name=%s]", name);
  }
  return flyweight;
}

Flyweight **get_flyweight_pool()
{
  return flyweight_factory_member_pool;
}

int get_flyweight_pool_size()
{
  return flyweight_factory_pool_size;
}

FlyweightFactory *flyweight_factory_constructor(char *name)
{
  FlyweightFactory *factory = (FlyweightFactory *)malloc(sizeof(FlyweightFactory));
  strncpy(factory->name, name, 50);
  factory->get_factory = &get_factory;
  factory->get_pool = &get_flyweight_pool;
  factory->get_pool_size = &get_flyweight_pool_size;
  return factory;
}

?

?

測試調(diào)用

?

   /**
   * 享元模式就是將已經(jīng)聲明過的實例或數(shù)據(jù)保存在內(nèi)存里,需要使用時則取出來,無需再次實例化和聲明。
   * 通過共享多個對象所共有的相同狀態(tài),以達到節(jié)省開銷的目的。
   * 享元模式分為內(nèi)部狀態(tài)和外部狀態(tài),內(nèi)部狀態(tài)基于享元對象共享,外部狀態(tài)則外部傳入或使用非享元類。
   */

  FlyweightFactory *flyweight_factory = flyweight_factory_constructor("flyweight_factory");
  // 假設(shè)有鋼琴和吉他,鋼琴使用者很多需要共享實例,而吉他每次創(chuàng)建新實例
  // // 2個一樣名稱的為共享對象,只創(chuàng)建1個實例,后面的返回緩存實例
  Flyweight *factory1 = flyweight_factory->get_factory("piano1");
  Flyweight *factory2 = flyweight_factory->get_factory("piano1");
  // 轉(zhuǎn)換類型測試
  ConcreteFlyweight *factory3 = (ConcreteFlyweight *)flyweight_factory->get_factory("piano2");
  Flyweight *factory4 = flyweight_factory->get_factory("piano2");

  factory1->operate(factory1, "factory1");
  factory2->operate(factory2, "factory2");
  factory3->operate(factory3, "factory3");
  factory4->operate(factory4, "factory4");

  // 打印全部共享對象
  Flyweight **flyweight_pool = flyweight_factory->get_pool();
  int pool_size = flyweight_factory->get_pool_size();
  for (int i = 0; i < pool_size; i++)
  {
    printf("\r\n 享元對象:%d %s", i, flyweight_pool[i]->name);
  }

  // 無需共享的對象,name雖然一樣,是不同的實例
  Flyweight *factory5 = (Flyweight *)unshared_concrete_flyweight_constructor("guitar1");
  UnsharedConcreteFlyweight *factory6 = unshared_concrete_flyweight_constructor("guitar1");
  factory5->operate(factory5, "factory5");
  factory6->operate(factory6, "factory6");
 

?

更多語言版本

不同語言實現(xiàn)設(shè)計模式:https://github.com/microwind/design-pattern文章來源地址http://www.zghlxwxcb.cn/news/detail-409729.html

到了這里,關(guān)于【享元設(shè)計模式詳解】C/Java/JS/Go/Python/TS不同語言實現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【迭代器設(shè)計模式詳解】C/Java/JS/Go/Python/TS不同語言實現(xiàn)

    【迭代器設(shè)計模式詳解】C/Java/JS/Go/Python/TS不同語言實現(xiàn)

    迭代器模式(Iterator Pattern),是一種結(jié)構(gòu)型設(shè)計模式。給數(shù)據(jù)對象構(gòu)建一套按順序訪問集合對象元素的方式,而不需要知道數(shù)據(jù)對象的底層表示。 迭代器模式是與集合共存的,我們只要實現(xiàn)一個集合,就需要同時提供這個集合的迭代器,就像Java中的Collection,List、Set、Map等

    2023年04月17日
    瀏覽(15)
  • 【模板方法設(shè)計模式詳解】C/Java/JS/Go/Python/TS不同語言實現(xiàn)

    模板方法模式(Template Method Pattern)也叫模板模式,是一種行為型模式。它定義了一個抽象公開類,包含基本的算法骨架,而將一些步驟延遲到子類中,模板方法使得子類可以不改變算法的結(jié)構(gòu),只是重定義該算法的某些特定步驟。不同的子類以不同的方式實現(xiàn)這些抽象方法

    2024年02月01日
    瀏覽(22)
  • 【備忘錄設(shè)計模式詳解】C/Java/JS/Go/Python/TS不同語言實現(xiàn)

    【備忘錄設(shè)計模式詳解】C/Java/JS/Go/Python/TS不同語言實現(xiàn)

    備忘錄模式(Memento Pattern)是一種結(jié)構(gòu)型設(shè)計模式。這種模式就是在不破壞封裝的條件下,將一個對象的狀態(tài)捕捉(Capture)住,并放在外部存儲起來,從而可以在將來合適的時候把這個對象還原到存儲起來的狀態(tài)。備忘錄模式常常與命令模式和迭代子模式一同使用。 備忘錄模式

    2023年04月20日
    瀏覽(27)
  • 【訪問者設(shè)計模式詳解】C/Java/JS/Go/Python/TS不同語言實現(xiàn)

    【訪問者設(shè)計模式詳解】C/Java/JS/Go/Python/TS不同語言實現(xiàn)

    訪問者模式(Visitor Pattern)是一種行為型模式。它封裝一個訪問者類,把各元素類的操作集合起來,目的是將數(shù)據(jù)結(jié)構(gòu)與數(shù)據(jù)操作分離。在不改變原有元素類數(shù)據(jù)結(jié)構(gòu)的前提下,改變了元素類的執(zhí)行算法。 當(dāng)某些較為穩(wěn)定的東西(數(shù)據(jù)結(jié)構(gòu)或算法),不想直接被改變但又想擴

    2024年02月02日
    瀏覽(22)
  • 【解釋器設(shè)計模式詳解】C/Java/Go/JS/TS/Python不同語言實現(xiàn)

    【解釋器設(shè)計模式詳解】C/Java/Go/JS/TS/Python不同語言實現(xiàn)

    解釋器模式(Interpreter Pattern)是一種行為型設(shè)計模式。這種模式實現(xiàn)了一個表達式接口,該接口解釋一個特定的上下文。這種模式常被用在 SQL 解析、符號處理引擎等。 解釋器模式常用于對簡單語言的編譯或分析實例中,為了掌握好它的結(jié)構(gòu)與實現(xiàn),必須先了解編譯原理中的

    2023年04月12日
    瀏覽(1388)
  • 【中介者設(shè)計模式詳解】C/Java/JS/Go/Python/TS不同語言實現(xiàn)

    【中介者設(shè)計模式詳解】C/Java/JS/Go/Python/TS不同語言實現(xiàn)

    中介者模式(Mediator Pattern)是一種行為型模式。它限制對象之間的直接交互,它用一個中介對象來封裝一系列的動作,以讓對象之間進行交流。中介者使各個對象不需要顯式地相互引用,從而使其耦合松散,而且可以獨立地改變它們之間的交互。 當(dāng)一些對象和其他對象緊密

    2023年04月19日
    瀏覽(28)
  • 【觀察者設(shè)計模式詳解】C/Java/JS/Go/Python/TS不同語言實現(xiàn)

    【觀察者設(shè)計模式詳解】C/Java/JS/Go/Python/TS不同語言實現(xiàn)

    觀察者模式(Observer Pattern)是一種行為型模式。它定義對象間的一種一對多的依賴關(guān)系,當(dāng)一個對象的狀態(tài)發(fā)生改變時,所有依賴于它的對象都得到通知并被自動更新。 觀察者模式使用三個類Subject、Observer和Client。Subject對象帶有綁定觀察者到Client對象和從Client對象解綁觀察

    2023年04月21日
    瀏覽(24)
  • [設(shè)計模式 Go實現(xiàn)] 結(jié)構(gòu)型~享元模式

    享元模式從對象中剝離出不發(fā)生改變且多個實例需要的重復(fù)數(shù)據(jù),獨立出一個享元,使多個對象共享,從而節(jié)省內(nèi)存以及減少對象數(shù)量。 flyweight.go flyweight_test.go

    2024年01月16日
    瀏覽(30)
  • js設(shè)計模式:享元模式

    js設(shè)計模式:享元模式

    當(dāng)需要處理很多非常類似操作的時候,可以創(chuàng)建可以共享的對象,并暴露接口供其他對象調(diào)用 這個對象內(nèi)包含這些操作的處理邏輯,可以優(yōu)化性能 ?

    2024年02月22日
    瀏覽(19)
  • 【Design Pattern 23種經(jīng)典設(shè)計模式源碼大全】C/Java/Go/JS/Python/TS等不同語言實現(xiàn)

    【Design Pattern 23種經(jīng)典設(shè)計模式源碼大全】C/Java/Go/JS/Python/TS等不同語言實現(xiàn)

    經(jīng)典設(shè)計模式源碼詳解,用不同語言來實現(xiàn),包括Java/JS/Python/TypeScript/Go等。結(jié)合實際場景,充分注釋說明,每一行代碼都經(jīng)過檢驗,確??煽俊?設(shè)計模式是一個程序員進階高級的必然選擇,不懂設(shè)計模式,就像寫文章不懂得層次,蓋房子沒有結(jié)構(gòu)。只有充分懂得設(shè)計之道,

    2023年04月11日
    瀏覽(24)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包