設計模式(策略,工廠,單例,享元,門面)+模板方法

文章目錄

  • 前提
  • 策略模式
    • 思想
    • 實現
    • 如何拓展
  • 模板方法
    • 存在的問題
    • 思想
    • 實現
    • 如何拓展
  • 工廠模式
    • 實現
    • 問題及解決(解耦)
      • 配置文件方式
      • 使用注解
  • 單例模式
    • 實現方式
      • 1,懶漢式(線程不安全)
      • 2,懶漢式(線程安全)
      • 3,餓漢式
      • 4,雙重校驗鎖機制(面)
      • 5,靜態內部類
      • 6,枚舉
    • 體現
  • 享元模式
  • 門面模式

前提

假設做一個需求,從文件中拿到數據并存在數據庫中,文檔有多種不同的類型,比如json,excel,csv等等。在做這個去求得在過程中,如何讓代碼變得優雅,可讀性高,耦合度低,易擴展。

策略模式

為解決上述問題,首先想到的是下面的代碼

public class XXX {public void export2Db(String filepath) {String type = getFileType(filepath);if ("csv".equals(type)) {// 讀取csv文件, 將數據保存到數據庫中, 此處省略500行代碼} else if ("json".equals(type)) {// 讀取json文件, 將數據保存到數據庫中, 此處省略500行代碼} else if ("excel".equals(type)) {// 讀取excel文件, 將數據保存到數據庫中, 此處省略500行代碼} else {throw new IllegalArgumentException("不支持該類型: " + type);}}
}

這里可以看到有很多問題,比如

  • type使用String類型的魔法值, 沒用枚舉.
  • 有幾個type就if判斷幾次, 假設新增txt文件類型, 又要修改代碼, 拓展性差.
  • 代碼核心代碼都寫到一個方法中, 一些邏輯無法復用, 而且會導致方法代碼巨多, 可讀性差, 后續也不好維護.

思想

策略模式是多態最好的體現, 也是解決這種標簽類的最好的方式之一.

策略模式的定義為: 在策略模式定義了一系列策略類,并將每個具體實現封裝在獨立的類中,使得它們可以互相替換。通過使用策略模式,可以在運行時根據需要選擇不同的算法,而不需要修改調用端代碼。是一種用來解決很多if else的方式.

實現

在本需求中, 需要寫一個頂層的策略接口FileExport, 新增 export2Db抽象方法.

然后根據不同類型的導出方式, 編寫CsvExport, ExcelExport, JsonExport三個策略類實現FileExport接口.

這里給出類圖和具體代碼.

public interface FileExport {void export2Db(String filepath);
}
public class CsvExport implements FileExport{@Overridepublic void export2Db(String filepath) {// 讀取csv文件, 將數據保存到數據庫中, 此處省略具體代碼}
}
public class ExcelExport implements FileExport {@Overridepublic void export2Db(String filepath) {// 讀取excel文件, 將數據保存到數據庫中, 此處省略具體代碼}
}
public class JsonExport implements FileExport{@Overridepublic void export2Db(String filepath) {// 讀取json文件, 將數據保存到數據庫中, 此處省略具體代碼}
}

有其他類依賴于我們的策略類, 那么就可以這樣使用, 需要哪個直接傳入對應的FileExport對象即可.

class XXX {// 注意這里參數類型聲明為FileExport接口, 這就意味著可以傳入任意的FileExport實現類public static void fileExport2Db(FileExport fileExport, String filepath) {fileExport.export2Db(filepath);}public static void main(String[] args) {FileExport excelExport = new ExcelExport();fileExport2Db(excelExport, "文件路徑");
}

如何拓展

使用策略模式后, 如果后續需求變更, 需要拓展其他文件格式導出到數據庫, 比如yml文件導出到數據庫. 那么我們新增YmlExport類, 實現FileExport即可.

模板方法

存在的問題

那么, 目前的代碼就不存在問題了嗎? 當然不是, 我們來看策略模式常見的兩個問題

  1. 不同實現類中代碼重復(靠模板方法解決)
  2. 如果想要根據傳入參數動態使用某個策略類, 還是避免不了大量if else

第一個問題:

當我們要實現具體將某中文件數據導出到數據庫時, 可以把大致過程劃分為以下幾步

  1. 檢查參數中的filepath是否合法
    • 路徑是否不為空
    • 文件是否存在
    • 文件類型是否和對應策略類類型一致
  2. 讀取文件數據到一個Java對象中
    • 對數據進行處理,比如去除空格之類的,這里就是簡單模擬一下
    • 注意, 有的文件讀取后需要處理, 有的不需要,這里假設json文件需要做額外處理, 但是csv和excel文件不需要讀取數據后做處理
  3. 保存到數據庫中
    • 將處理后的數據轉為數據表對應的實體類
    • 使用mybatis/jpa/jdbc等orm工具保存到數據庫中

通過上述的過程我們發現,每個策略類的具體實現經歷的大體步驟/框架都相同,只有少部分的代碼/邏輯不同,如果每個類都自己寫自己的具體實現,就會導致大量的重復代碼。

第二個問題:

什么是動態使用策略類?簡而言之, 就是根據傳入的參數, 或者根據某些情況來決定使用哪個策略類來處理.

現在只能傳入FileExport類型的參數,如果我要傳入String類型的filePath或者其他標識文件類型的參數,就又會導致因判斷屬于哪個FileExport而產生if-else,代碼如下

public class XXX {public void import2Db(String filepath) {String fileType = getFileType(filepath);FileExport fileExport;if ("csv".equals(fileType)) {fileExport = new CsvExport();fileExport.export2Db(filepath);} else if ("json".equals(fileType)) {fileExport = new JsonExport();fileExport.export2Db(filepath);} else if ("excel".equals(fileType)) {fileExport = new ExcelExport();fileExport.export2Db(filepath);} else {throw new IllegalArgumentException("不支持該類型: " + fileType);}}
}

思想

接下來, 我們用模板方法模式來解決第一個問題, 也就是不同實現類中的代碼重復問題。

模板方法模式會在抽象類或者接口中定義一個算法的整體流程, 該流程中會調用不同的方法. 這些方法的具體實現交給不同的子類完成. 也就是說它適合整體流程固定, 具體細節不同的場景.

實現

定義一個抽象類來當模板類

  • 具體方法void check(String filepath): 檢查filepath是否合法
  • 具體方法 void fileDataExport2Db(FileData fileData): 導出數據到數據庫
  • 實現void export2Db(String filepath): 調用以上四個抽象方法來完成文件導出到數據庫
  • 抽象方法needProcessData():是否需要進行數據處理
  • 抽象方法 FileData readFile(String filepath): 來讀取文件數據
  • 抽象方法 FileData processData(FileData fileData): 來處理數據
public interface FileExport {void export2Db(String filepath);
}
public abstract class AbstractFileExport implements FileExport {@Overridepublic void export2Db(String filepath) {check(filepath);FileData fileData = readFile(filepath);// 鉤子函數, 子類決定是否需要對數據進行處理if (needProcessData()) {fileData = processData(fileData);}fileDataExport2Db(fileData);}protected void check(String filepath) {// 檢查filepath是否為空if (StrUtil.isBlank(filepath)) {throw new IllegalArgumentException("filepath為空");}// 檢查filepath是否存在, 是否為文件File file = new File(filepath);if (!file.exists() || !file.isFile()) {throw new IllegalArgumentException("filepath不存在或者不是文件");}// 檢查文件類型是否為子類可以處理的類型 (用了hutool的FileTypeUtil工具)String type = FileTypeUtil.getType(file);if (!Objects.equals(getFileType(), type)) {throw new IllegalArgumentException("文件類型異常: " + type);}}/*** 數據類型轉換并保存到數據庫, 這是通用操作, 所以寫在父類中*/protected void fileDataExport2Db(FileData fileData) {System.out.println("將處理后的數據轉為數據表對應的實體類");System.out.println("使用mybatis/jpa/jdbc等orm工具保存到數據庫中");}/*** 如果子類要處理數據, needProcessData()返回true, 并重新該方法*/protected FileData processData(FileData fileData) {throw new UnsupportedOperationException();}/*** 獲取子類能處理的文件類型, check()方法會用到*/protected abstract String getFileType();/*** 鉤子函數, 讓子類決定是否需要處理數據*/protected abstract boolean needProcessData();protected abstract FileData readFile(String filepath);
}
public class JsonExport extends AbstractFileExport {private static final String FILE_TYPE = "json";@Overrideprotected String getFileType() {return FILE_TYPE;}@Overrideprotected boolean needProcessData() {return false;}protected FileData readFile(String filepath) {System.out.println("以json方式讀取filepath中的文件");System.out.println("將讀取后的結果轉為通用的FileData類型");return new FileData();}
}

大量重復代碼和流程都被抽取到父類中了. 策略模式中出現的代碼重復問題就解決了.

如何拓展

和之前類似, 如果后續需求變更, 需要拓展其他文件格式導出到數據庫, 比如yml文件導出到數據庫. 那么我們新增YmlExport類, 繼承AbstractFileExport即可.

由于AbstractFileExport規定了統一流程, 且提供了 check(), fileDataExport2Db()等方法, 所以后續拓展起來代碼量也會更少, 更方便.

工廠模式

前面還剩下一個問題,就是根據傳入的參數動態的調用。通過工廠+枚舉類來實現。

工廠模式就是用來創建對象的,可以根據參數的不同返回不同的實例。

三種工廠模式的區別-CSDN博客

這里使用簡單工廠模式

實現

枚舉類

@Getter
@AllArgsConstructor
@ToString
public enum FileType {JSON("json"),CSV("csv");private final String type;private static final Map<String, FileType> VALUE_MAP = Arrays.stream(values()).collect(Collectors.toMap(FileType::getType,Function.identity(),(existing, replacement)->replacement));public static FileType stringParseObject(String fileType) {if(!VALUE_MAP.containsKey(fileType)){throw new IllegalArgumentException("不支持的文件類型");}return VALUE_MAP.get(fileType);}
}

工廠類

public class FileExportFactory {private static final Map<FileType, FileExport> CACHE = new HashMap<>();static {CACHE.put(FileType.JSON, new JsonExport());CACHE.put(FileType.CSV, new CsvExport());}public static FileExport getFileExport(FileType fileType) {if (!CACHE.containsKey(fileType)) {throw new IllegalArgumentException("找不到對應類型:" + fileType.getType());}return CACHE.get(fileType);}public static FileExport getFileExport(String type) {FileType fileType = FileType.from(type);return getFileExport(fileType);}
}

問題及解決(解耦)

可以發現,這種情況下如果要增加新的新的文件類型,那么就需要更改FileExportFactory工廠類的代碼,違反了OOP原則中的開閉原則(當應用需求發生改變的時候,我們盡量不要修改源代碼,可以對其進行擴展,擴展的功能塊不會影響到原來的功能塊)。

解決方法

spring的解決方法有兩種

  • @Component/@Bean,使用注解方式,動態添加新的文件類型
  • spring.factories,使用kv鍵值對,配置了需要自動裝配類的全類名

配置文件方式

在resource文件夾下的yml配置文件中定義需要用到的全類名,然后讀取出來。也可以通過反射拿到所有實現FileExport接口的類,然后篩選拿到需要用到的類。

這里是在枚舉類中定義好相應的全類名,這樣在工廠類中可以直接拿到。理由:實現類很少,操作簡便。

枚舉類

@Getter
@AllArgsConstructor
@ToString
public enum FileType {JSON("json", "com.luxiya.design.JsonExport"),CSV("csv","com.luxiya.design.CsvExport");private final String type;private final String className;private static final Map<String, FileType> VALUE_MAP = Arrays.stream(values()).collect(Collectors.toMap(FileType::getType,Function.identity(),(existing, replacement)->replacement));public static FileType stringParseObject(String fileType) {if(!VALUE_MAP.containsKey(fileType)){throw new IllegalArgumentException("不支持的文件類型");}return VALUE_MAP.get(fileType);}@SneakyThrowspublic FileExport classNameParseObject() {Class<?> clazz = Class.forName(this.getClassName());return (FileExport) clazz.newInstance();}
}

工廠類

public class FileExportFactory {private static final Map<FileType, FileExport> Cache;static {Cache = Arrays.stream(FileType.values()).map(fileType -> new Pair<>(fileType, fileType.classNameParseObject())).collect(Collectors.toMap(Pair::getKey,Pair::getValue,(existing, replacement)-> replacement));}public static FileExport getFileExport(FileType fileType) {if (!Cache.containsKey(fileType)) {throw new IllegalArgumentException("不支持的文件類型");}return Cache.get(fileType);}public static FileExport getFileExport(String fileType) {FileType fileTypeNew = FileType.stringParseObject(fileType);System.out.println(fileTypeNew);return getFileExport(fileTypeNew);}
}

這樣如果新增YmlExport類,增加實現類,然后在枚舉類中修改。

使用注解

使用注解實現解耦的流程大概如下

  1. 定義注解,并在相應的類上添加注解。
  2. 通過反射機制拿到添加了注解的類,放入工廠。

定義注解,并在JsonExport和CsvExport類上添加該注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FileExportComponent {
}

工廠類拿到所需類

public class FileExportFactory {private static final Map<FileType, FileExport> Cache;static {Set<Class<?>> classes = ClassUtil.scanPackage("com.luxiya.design", FileExport.class::isAssignableFrom);Cache = classes.stream().filter(ClassUtil::isNormalClass).filter(clazz -> AnnotationUtil.hasAnnotation(clazz, FileExportComponent.class)).map(ReflectUtil::newInstance).map(fileExport -> (FileExport) fileExport).collect(Collectors.toMap(FileExport::getSupportType,Function.identity(),(existing, replacement) -> replacement));}public static FileExport getFileExport(FileType fileType) {if (!Cache.containsKey(fileType)) {throw new IllegalArgumentException("不支持的文件類型");}return Cache.get(fileType);}public static FileExport getFileExport(String fileType) {FileType fileTypeNew = FileType.stringParseObject(fileType);System.out.println(fileTypeNew);return getFileExport(fileTypeNew);}
}

單例模式

保證一個類只有一個實例,并提供一個全局訪問他的訪問點,避免一個全局使用的類頻繁的創建與銷毀。

實現方式

1,懶漢式(線程不安全)

**是否 Lazy 初始化:**是

**是否多線程安全:**否

**實現難度:**易

**描述:**這種方式是最基本的實現方式,這種實現最大的問題就是不支持多線程。因為沒有加鎖 synchronized,所以嚴格意義上它并不算單例模式。
這種方式 lazy loading 很明顯,不要求線程安全,在多線程不能正常工作。

public class Singleton {  private static Singleton instance;  private Singleton (){}  public static Singleton getInstance() {  if (instance == null) {  instance = new Singleton();  }  return instance;  }  
}

2,懶漢式(線程安全)

**是否 Lazy 初始化:**是

**是否多線程安全:**是

**實現難度:**易

**描述:**這種方式具備很好的 lazy loading,能夠在多線程中很好的工作,但是,效率很低,99% 情況下不需要同步。

  • 優點:第一次調用才初始化,避免內存浪費。
  • 缺點:必須加鎖 synchronized 才能保證單例,但加鎖會影響效率。
  • getInstance() 的性能對應用程序不是很關鍵(該方法使用不太頻繁)
public class Singleton {  private static Singleton instance;  private Singleton (){}  public static synchronized Singleton getInstance() {  if (instance == null) {  instance = new Singleton();  }  return instance;  }  
}

3,餓漢式

**是否 Lazy 初始化:**否

**是否多線程安全:**是

**實現難度:**易

**描述:**這種方式比較常用,但容易產生垃圾對象。

  • 優點:沒有加鎖,執行效率會提高。
  • 缺點:類加載時就初始化,浪費內存。
public class Singleton {  private static Singleton instance = new Singleton();  private Singleton (){}  public static Singleton getInstance() {  return instance;  }  
}

4,雙重校驗鎖機制(面)

**是否 Lazy 初始化:**是

**是否多線程安全:**是

**實現難度:**較復雜

**描述:**這種方式采用雙鎖機制,安全且在多線程情況下能保持高性能。
getInstance() 的性能對應用程序很關鍵。

    private static volatile Singleton singleton;private Singleton(){}public static Singleton getInstance(){if(singleton == null){synchronized (Singleton.class){if(singleton == null){singleton = new Singleton();}}}return singleton;}

5,靜態內部類

**是否 Lazy 初始化:**是

**是否多線程安全:**是

利用 ClassLoader 的特性

  • 類的靜態變量在第一次加載類時初始化,JVM 保證這一過程是線程安全的。
  • 靜態內部類(如SingletonHolder)不會隨外部類(Singleton)的加載而加載,只有在被顯式調用時才加載。
public class Singleton {private static class SingletonHolder {private static final Singleton INSTANCE = new Singleton();}private Singleton() {}public static Singleton getInstance() {return SingletonHolder.INSTANCE;}
}

6,枚舉

**是否 Lazy 初始化:**否

**是否多線程安全:**是

**實現難度:**易

**描述:**這種實現方式還沒有被廣泛采用,但這是實現單例模式的最佳方法。它更簡潔,自動支持序列化機制,絕對防止多次實例化。

public enum Singleton {  INSTANCE;  public void whateverMethod() {  }  
}

體現

上述需求中,其實FileFactory工廠類的Map存儲了所有FileExport的實現類,所用代碼中用到的都是Map中的實現類,就是單例模式。

且用到的是枚舉創建的對象,而且不會被反射和反序列化破壞。

享元模式

通過共享對象來減少系統對象的數量,本質就是緩存對象,降低內存消耗。

享元(Flyweight)的核心思想很簡單:如果一個對象實例一經創建就不可變,那么反復創建相同的實例就沒有必要,直接向調用方返回一個共享的實例就行,這樣即節省內存,又可以減少創建對象的過程,提高運行速度。

享元模式在Java標準庫中有很多應用。我們知道,包裝類型如ByteInteger都是不變類,因此,反復創建同一個值相同的包裝類型是沒有必要的。以Integer為例,如果我們通過Integer.valueOf()這個靜態工廠方法創建Integer實例,當傳入的int范圍在-128~+127之間時,會直接返回緩存的Integer實例:

// 享元模式
public class Main {public static void main(String[] args) throws InterruptedException {Integer n1 = Integer.valueOf(100);Integer n2 = Integer.valueOf(100);System.out.println(n1 == n2); // true}
}

對于Byte來說,因為它一共只有256個狀態,所以,通過Byte.valueOf()創建的Byte實例,全部都是緩存對象。

因此,享元模式就是通過工廠方法創建對象,在工廠方法內部,很可能返回緩存的實例,而不是新創建實例,從而實現不可變實例的復用。

其實FileFactory工廠類的Map就是共享對象,運用到了享元模式。

門面模式

一文搞懂設計模式—門面模式-CSDN博客

門面模式(Facade Pattern)也叫做外觀模式,是一種結構型設計模式。它提供一個統一的接口,封裝了一個或多個子系統的復雜功能,并向客戶端提供一個簡單的調用方式。通過引入門面,客戶端無需直接與子系統交互,而只需要通過門面來與子系統進行通信。

角色職責
門面(Facade)提供統一接口,封裝子系統的功能調用,隱藏內部細節。
子系統(Subsystem)實現具體功能的多個模塊或類,不直接對外暴露,由門面協調調用。
客戶端(Client)通過門面對象間接調用子系統功能,無需依賴具體子系統類。

簡單門面類

public class FileExportClient {public static void exportToDb(String filePath){String type = FileTypeUtil.getTypeByPath(filePath);FileExport fileExport = FileExportFactory.getFileExport(type);fileExport.export(filePath);}public static void exportToDb(File file){String filePath = file.getAbsolutePath();exportToDb(filePath);}}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/86783.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/86783.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/86783.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

libarchive壓縮解壓文件

存在中文亂碼問題 官網&#xff1a; libarchive - 用于讀取和寫入 tar、cpio、zip、ISO 和其他存檔格式的 C 庫和命令行工具 GitHub GitHub源碼&#xff1a;Bluewind/libarchive: Multi-format archive and compression library (github.com) 參考&#xff1a; C archive_w…

AutoGPT,自主完成復雜任務

AutoGPT是一個開源的AI Agent項目&#xff0c;它的核心目標是讓AI能夠自主完成復雜任務&#xff0c;而不僅僅是回答單個問題。簡單來說&#xff0c;它讓AI具備了"自主思考和行動"的能力。 1. AutoGPT的核心概念 什么是AI Agent&#xff1f; AI Agent&#xff08;智…

lambda、function基礎/響應式編程基礎

lambda表達式 只要是函數式接口&#xff08;接口內只有一個未實現的方法&#xff0c;可以有其它默認方法&#xff09;&#xff0c;就可以用lambda表達式&#xff0c;也就是快速new一個匿名內部類。 實例化接口的三種方式 繼承接口&#xff0c;并實現接口 直接實現匿名內部類 …

OpenTiny 體驗官實操活動 | 快速體驗 TinyVue 組件庫的智能化交互能力

實驗簡介 通過體驗基于標準 MCP 協議的 Web 智能組件庫——TinyVue&#xff0c;開發者可以了解 AI 智能體控制 TinyVue 智能組件的各類行為。本次實驗主要是在 TinyVue 官網上&#xff0c;開發者能夠通過 AI 對話框&#xff0c;以語音或文字方式與網站組件進行互動&#xff0c…

秋招Day15 - Redis - 基礎

什么是Redis&#xff1f; Redis是一種基于鍵值對的NoSQL數據庫。 主要的特點是把數據放在內存中&#xff0c;讀寫速度相比于磁盤會快很多。 對于性能要求很高的場景&#xff0c;比如緩存熱點數據&#xff0c;防止接口爆刷&#xff0c;都會用到Redis Redis還支持持久化&…

權限提升-工作流

一、Windows 權限提升 操作階段 對應工具 說明 系統補丁與漏洞查詢 systeminfo、WindowsVulnScan、wesng 提取 KB 補丁號&#xff0c;匹配 CVE 漏洞&#xff08;如 CVE-2020-1054&#xff09; 內核漏洞提權 MSF&#xff08;local_exploit_suggester&#xff09;、CVE 對…

c++手撕線程池

C手撕線程池 #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <time.h>#define LL_ADD(item, list) do{ \item->prev NULL; \item->next list; \if…

cocos creator 3.8 - 精品源碼 - 六邊形消消樂(六邊形疊疊樂、六邊形堆疊戰士)

cocos creator 3.8 - 精品源碼 - 六邊形消消樂 游戲介紹功能介紹免費體驗下載開發環境游戲截圖免費體驗 游戲介紹 六邊形堆疊戰士(六邊形消消消)是一款脫胎于2048、1010&#xff0c;基于俄羅斯方塊的魔性方塊達人小游戲&#xff0c;可以多方向多造型消除哦&#xff01; 功能介…

3ds Max高效運行配置核心要素

要保障3ds Max流暢運行&#xff0c;需圍繞計算性能、圖形處理、數據吞吐三大維度構建硬件體系。不同工作環節對硬件需求存在顯著差異&#xff1a; 一、核心組件配置原則 CPU&#xff1a;線程與頻率雙優化 建模/視口操作&#xff1a;依賴高主頻&#xff08;建議≥4.0GHz&#…

實變與泛函題解-心得筆記【16】

文章目錄 集合參考文獻 集合 參考文獻 《實變函數論與泛函分析》

道路交通標志檢測數據集-智能地圖與導航 交通監控與執法 智慧城市交通管理-2,000 張圖像

道路交通標志檢測數據集 &#x1f4e6; 已發布目標檢測數據集合集&#xff08;持續更新&#xff09;&#x1f6a7; 道路交通標志檢測數據集介紹&#x1f4cc; 數據集概覽包含類別 &#x1f3af; 應用場景&#x1f5bc; 數據樣本展示 YOLOv8 訓練實戰&#x1f4e6; 1. 環境配置 …

一、jenkins介紹和gitlab部署

一、jenkins介紹 jenkins和持續集成的關系 Jenkins 是實現持續集成&#xff08;CI&#xff09;最流行的自動化工具&#xff0c;它負責自動構建、測試和部署代碼&#xff0c;確保團隊能頻繁且可靠地集成代碼變更。 持續集成和敏捷開發的關系 敏捷開發是一種"快速迭代、…

k3s or kubesphere helm安裝報錯dial tcp 127.0.0.1:8080: connect: connection refused

在安裝kubesphere時報錯 Error: Kubernetes cluster unreachable: Get "http://localhost:8080/version": dial tcp 127.0.0.1:8080: connect: connection refused helm.go:92: 2025-06-27 15:14:43.30908177 0000 UTC m0.033127135 [debug] Get "http://localh…

使用datafusion和tpchgen-rs進行完整的TPCH 22個查詢的基準測試

1.從源碼編譯bench二進制文件。 下載datafusion源碼, 解壓到目錄&#xff0c;比如/par/dafu&#xff0c; cd /par/dafu/benchmarks export CARGO_INCREMENTAL1 export PATH/par:/par/mold240/bin:$PATH因為mold默認使用并行編譯&#xff0c;而這些二進制文件很大&#xff0c;如…

【軟考高項論文】論信息系統項目的干系人管理

摘要 在信息系統項目管理里&#xff0c;干系人管理極為關鍵&#xff0c;它不僅決定項目成敗&#xff0c;還對項目進度、質量和成本有著直接影響。本文結合作者2024年6月參與管理的信息系統項目&#xff0c;詳細闡述了項目干系人管理的過程&#xff0c;分析了干系人管理與溝通管…

PB應用變為Rust語言方案

從PB(PowerBuilder)遷移到現代開發軟件 PowerBuilder(PB)作為早期的快速應用開發工具,曾廣泛應用于企業級數據庫應用開發。隨著技術發展,PB逐漸面臨以下挑戰,促使企業轉向現代開發工具: 技術陳舊與維護困難 PB的架構基于較老的客戶端-服務器模式,難以適應云原生、微…

【大模型】Query 改寫常見Prompt 模板

下面對常見的幾種“Query 改寫”Prompt 模板進行中英文對照&#xff0c;并在注釋中給出中文說明&#xff0c;幫助中國用戶快速理解與使用。 根據調研&#xff0c;企業級 Query 改寫模塊需要覆蓋多種常見場景&#xff0c;包括拼寫糾錯、中英混合、省略上下文、多義詞擴展、專業術…

西門子S7-200 SMART PLC:小型自動化領域的高效之選

在工業自動化領域&#xff0c;小型PLC作為設備控制的核心組件&#xff0c;其性能、靈活性和性價比始終是用戶關注的重點。西門子推出的S7-200 SMART可編程控制器&#xff0c;憑借對中國市場需求的精準把握&#xff0c;成為了小型自動化解決方案的標桿產品。本文將從產品亮點、技…

使用iperf3測試網絡的方法

深入掌握網絡性能測試&#xff1a;iperf3全指南 在網絡優化、故障排查和帶寬驗證中&#xff0c;iperf 是工程師必備的利器。這款開源工具通過模擬數據流&#xff0c;精準測量??帶寬、抖動、丟包率??等核心指標。本文將結合實戰經驗&#xff0c;詳解iperf的安裝、參數配置和…

Level2.11繼承

一、繼承 #動物# #老虎、獅子、大象 #動物有共性 ##定義一個動物&#xff1a;1.有4條腿&#xff1b;2.陸地上跑&#xff1b;3.需要進食&#xff08;屬性能力&#xff09; ##貓&#xff1a;同上&#xff08;繼承了動物的屬性和能力&#xff09; ##老鼠&#xff1a;同上#Python…