設計模式1:創建型模式

設計模式1:創建型模式
設計模式2:結構型模式(編寫中)
設計模式3:行為型模式(編寫中)

前言

設計模式是軟件開發中經過驗證的可復用解決方案,它們源自實踐、提煉于經驗,并在面向對象編程中扮演著關鍵角色。GoF(Gang of Four)設計模式分為創建型結構型行為型三大類,共23種。設計模式的核心價值在于提高代碼的可維護性、可擴展性和可復用性,同時遵循軟件設計原則。
本文介紹創建型模式。創建型模式關注對象的創建過程,通過將對象的創建與使用分離,使系統能夠靈活地控制對象的生成方式。

1 單例模式(Singleton)

單例模式確保一個類只有一個實例,并提供一個全局訪問點。它適用于需要嚴格控制實例數量的場景,如全局配置、數據庫連接池和日志系統等。
核心思想:通過私有構造函數限制外部實例化,使用靜態變量保存唯一實例,并通過靜態方法提供全局訪問。
Java實現:

public class President {private static President instance; // 唯一private President() {} // 禁止外部newpublic static President getInstance() { if (instance == null) {  instance = new President(); // 延遲初始化  }  return instance; } 
}// 使用示例 
President p1 = President.getInstance(); 
President p2 = President.getInstance(); 
System.out.println(p1 == p2); // true(同一個) 

適用場景:需要全局唯一訪問點的場景,如配置管理、資源共享等。
優點:節省內存,避免重復創建;提供全局訪問點。
缺點:多線程環境下需加鎖(可用雙重檢查鎖優化);破壞了單一職責原則。

2 工廠方法模式(Factory Method)

工廠方法模式定義一個創建對象的接口,但由子類決定實例化哪一個類,將實例化延遲到子類。它適用于需要解耦對象創建與使用,同時允許擴展的場景。
核心思想:通過抽象工廠類定義創建對象的方法,具體實現由子類完成,遵循開閉原則。
Java實現:

// 抽象產品類 
interface Transport {  void deliver(); 
}
// 具體產品類 
class Truck implements Transport {  public void deliver() {  System.out.println(“陸運”);  } 
}
class Ship implements Transport {  public void deliver() {  System.out.println(“海運”);  } 
}
// 抽象工廠類 
interface Logistics {  Transport createTransport(); 
}
// 具體工廠類 
class RoadLogistics implements Logistics {  public Transport createTransport() {  return new Truck();  } 
}
class SeaLogistics implements Logistics {  public Transport createTransport() {  return new Ship();  }
}// 使用示例 
Logistics roadLogistics = new RoadLogistics(); 
Transport truck = roadLogistics.createTransport(); 
truck.deliver(); 

適用場景:對象創建邏輯復雜(如依賴配置、外部服務),需解耦對象創建與使用 。
優點:擴展性強,新增產品只需添加子類;遵循開閉原則。
缺點:每新增一個產品就要新增一個工廠類;類層次結構可能變得復雜。

3 抽象工廠模式(Abstract Factory)

抽象工廠模式提供一個創建一系列相關或相互依賴對象的接口,而無須指定它們的具體類。它適用于需要創建多個相關對象家族的場景。
核心思想:通過工廠接口定義一組產品對象的創建方法,具體實現由子類完成,實現產品家族的統一創建。
Java實現:

// 產品接口 
interface Phone {  void call(); 
}
interface Earphone {  void play(); 
}
// 蘋果產品家族 
class iPhone implements Phone {  public void call() {  System.out.println(“iPhone通話”);  } 
}
class AirPods implements Earphone {  public void play() {  System.out.println(AirPods播放”);  } 
}
// 小米產品家族 
class MiPhone implements Phone {  public void call() {  System.out.println(“小米手機通話”);  } 
}
class MiEarphone implements Earphone {  public void play() {  System.out.println(“小米耳機播放”);  } 
}
// 抽象工廠接口 
interface TechFactory {  Phone createPhone();  Earphone createEarphone(); 
}
// 具體工廠類 
class AppleFactory implements TechFactory {  public Phone createPhone() {  return new iPhone();  }public Earphone createEarphone() {  return new AirPods();  } 
}
class MiFactory implements TechFactory {  public Phone createPhone() {  return new MiPhone();  }public Earphone createEarphone() {  return new MiEarphone();  } 
}// 使用示例 
TechFactory factory = new AppleFactory(); 
Phone phone = factory.createPhone(); 
Earphone earphone = factory.createEarphone();
phone.call(); // iPhone通話 
earphone.play(); // AirPods播放 

適用場景:跨平臺應用(如Windows/macOS按鈕)、產品線擴展等。
優點:產品族統一創建,保證一致性;擴展性強,新增產品族只需添加子類。
缺點:工廠類數量隨產品族增加而增加;難以支持產品族的動態切換。

4 建造者模式(Builder)

建造者模式將一個復雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。它適用于需要構建復雜對象,且對象的構建過程可能變化的場景。
核心思想:通過建造者類逐步構建對象,最后通過build方法返回完整對象;使用導演類控制構建過程。
Java實現:

// 奶茶產品類 
class BubbleTea {  private String size;  private boolean ice;  private List toppings;// 私有構造函數  private BubbleTea(Builder builder) {  this.size = builder.size;  this.ice = builder.ice;  this.toppings = builder.toppings;  }// 獲取建造者  public static class Builder {  private String size = “中杯”;  private boolean ice = true;  private List toppings = new ArrayList<>();public Builder size(String size) {  this.size = size;  return this;  }public Builder ice(boolean ice) {  this.ice = ice;  return this;  }public Builder addTopping(Topping topping) {  toppings.add(topping);  return this;  }public BubbleTea build() {  return new BubbleTea(this);  }  }// 配料枚舉  enum Topping {  波霸, 珍珠, 椰果, 西米  } 
}// 使用示例 
BubbleTea bubbleTea = new BubbleTea.Builder()  .size(“大杯”)  .ice(false)  .addTopping(BubbleTea.Topping.波霸)  .addTopping(BubbleTea.Topping.珍珠)  .build();
System.out.println(“奶茶規格:” + bubbleTea.size); 
System.out.println(“是否加冰:” + (bubbleTea.ice ? “是” : “否”)); 
System.out.println(“配料:” + bubbleTea.toppings); 

適用場景:構建復雜對象(如訂單、配置文件)、參數較多的構造函數等。
優點:參數解耦,構建過程清晰;支持部分構建和鏈式調用。
缺點:類數量增加;過度使用可能增加代碼復雜度。

5 原型模式(Prototype)

原型模式通過復制現有對象來創建新對象,避免重復初始化。它適用于對象創建成本高,或需要快速復制已有對象的場景。
核心思想:通過克隆方法復制對象,創建新實例;使用深拷貝或淺拷貝控制復制深度。
Java實現:

// 原型接口 
interface Shape extends Cloneable {  void draw();  Shape clone(); 
}
// 具體形狀類 
class Circle implements Shape {  private String color;public Circle(String color) {  this.color = color;  }public void draw() {  System.out.println(“繪制圓形,顏色:” + color);  }@Override  public Shape clone() {  try {  return (Shape) super.clone();  } catch (CloneException e) {  throw new RuntimeException(e);  }  } 
}
class Square implements Shape {  private int sideLength;public Square(int sideLength) {  this.sideLength = sideLength;  }public void draw() {  System.out.println(“繪制正方形,邊長:” + sideLength);  }@Override  public Shape clone() {  try {  return (Shape) super.clone();  } catch (CloneException e) {  throw new RuntimeException(e);  }  } 
}// 使用示例 
Circle circle = new Circle(“紅色”); 
Shape circleClone = circle.clone();
circleClone.draw(); // 繪制圓形,顏色:紅色

適用場景:對象創建成本高(如數據庫連接、圖形對象)、需要快速復制已有對象等 [3]。
優點:性能高效,避免重復初始化;代碼簡潔,直接使用克隆方法 [3]。
缺點:深拷貝實現復雜;不適合不可克隆的對象。

6 對象池模式(Object Pool)

對象池模式是單例模式的擴展,通過預先創建并管理對象集合,減少頻繁創建/銷毀的開銷 。它適用于資源密集型對象(如數據庫連接、網絡套接字)的高效復用場景。
核心思想:通過對象池管理對象的生命周期,包括對象的分配、重用和釋放;使用工廠模式創建和銷毀對象 。
Java實現:

// 池化對象接口 
interface PoolableObject {  void activate(); // 激活對象  void passivate(); // 使對象空閑 
}
// 對象池接口 
interface ObjectPool {     T borrowObject();  // 獲取對象     void returnObject(T obj);  // 歸還對象     void clear();      // 清除池中對象 
}
// 對象池工廠接口 
interface PoolableObjectFactory {     T makeObject();     // 創建對象     void destroyObject(T obj);  // 銷毀對象     void activateObject(T obj);  // 激活對象     void passivateObject(T obj);  // 使對象空閑 
}
// 具體實現 
class SimpleObjectPool implements ObjectPool {private final PoolableObjectFactory factory;     private final List pool = new ArrayList<>();     private final int maxPoolSize;public SimpleObjectPool(PoolableObjectFactory factory, int maxPoolSize) {         this.factory = factory;         this.maxPoolSize = maxPoolSize;         // 初始化池         for (int i = 0; i < maxPoolSize; i++) {             T obj = factory.makeObject();             obj.passivate();             pool.add(obj);        }     }@Override  public T borrowObject() {  // 獲取空閑對象  for (T obj : pool) {  if (!obj.isActive()) {  obj.activate();  return obj;  }}  // 如果池已滿,可能需要創建新對象  if (pool.size() < maxPoolSize) {  T obj = factory.makeObject();  obj.activate();  pool.add(obj);  return obj;  }  // 池已滿,無法獲取對象  return null;  }@Override  public void returnObject(T obj) {  if (pool.contains(obj)) {  obj.passivate();  } else {  // 可能需要處理不屬于池的對象  factory.destroyObject(obj);  }  }@Override  public void clear() {  for (T obj : pool) {  factory.destroyObject(obj);  }  pool.clear();  } 
}
// 使用示例 
// 定義池化對象 
class DatabaseConnection implements PoolableObject {  private boolean active = false;public void activate() {  this.active = true;  System.out.println(“連接激活”);  }public void passivate() {  this.active = false;  System.out.println(“連接空閑”);  }public boolean.isActive() {  return active;  }public void connect() {  System.out.println(“建立數據庫連接”);  }public void disconnect() {  System.out.println(“關閉數據庫連接”);  } 
}
// 定義工廠 
class DatabaseConnectionFactory implements PoolableObjectFactory {     @Override     public DatabaseConnection makeObject() {         return new DatabaseConnection();     }@Override  public void destroyObject(DatabaseConnection obj) {  obj.disconnect();  }@Override  public void activateObject(DatabaseConnection obj) {  obj.activate();  }@Override  public void passivateObject(DatabaseConnection obj) {  obj.passivate();  } 
}
// 使用對象池 
ObjectPool pool = new SimpleObjectPool<>(new DatabaseConnectionFactory(), 10);
DatabaseConnection conn = pool borrowObject(); 
// 使用連接 
conn.connect(); 
// 歸還連接 
pool.returnObject(conn); 

適用場景:資源密集型對象(如數據庫連接、網絡套接字、游戲中的粒子系統)的高效復用。
優點:減少對象創建和銷毀的開銷;提高系統性能。
缺點:增加系統復雜度;管理池對象需要額外資源。

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

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

相關文章

React--》規劃React組件庫編碼規范與標準 — Button篇

目前前端組件化已經成為前端開發的核心思想之一&#xff0c;在這篇文章中將深入探討如何規劃一個規范的Button組件&#xff0c;讓它不僅能高效支持不同的功能需求還能確保跨項目、跨團隊的一致性&#xff0c;拋磚引玉的方式引出后面組件庫的其他組件的開發&#xff01; 目錄 B…

中科米堆CASAIM金屬件自動3d測量外觀尺寸三維檢測解決方案

金屬零部件的外觀尺寸檢測直接關系到產品的裝配精度和使用性能。CASAIM基于激光掃描技術的自動化三維掃描系統&#xff0c;為金屬加工行業提供了高效的自動3D測量解決方案&#xff0c;有效解決了傳統檢測方式效率低、覆蓋面有限等問題。激光掃描技術在金屬件測量中優勢明顯。與…

開源數據同步中間件,支持MySQL、Oracle

DBSyncer&#xff08;英[dbs??k??(r)]&#xff0c;美[dbs??k??(r) 簡稱dbs&#xff09;是一款開源的數據同步中間件&#xff0c;提供MySQL、Oracle、SqlServer、PostgreSQL、Elasticsearch(ES)、Kafka、File、SQL等同步場景。支持上傳插件自定義同步轉換業務&#xff0…

中英混合的語音識別XPhoneBERT 監督的音頻到音素的編碼器結合 f0 特征LID

完整項目包獲取點擊文末名片完成一個 Code-Switching&#xff08;中英混合&#xff09;的語音識別系統&#xff0c;整個流程如下思路進行&#xff1a; 163. (Step 1) 訓練音頻到音素的編碼器&#xff08;Audio → Phoneme Encoder&#xff09; 你已經完成了此部分。核心思路是利…

Param關鍵字的使用

1&#xff1a;當一個方法的某一個參數個數不固定的時候&#xff0c;可以使用Param2:可變的方法參數必須定義為數組類型3&#xff1a;該參數必須放在方法參數的最后&#xff0c;應且只有一個4&#xff1a;參數必須為一維數組5&#xff1a;params不能和ref和out組合使用namespace…

京東云輕量云服務器與騰訊云域名結合配置網站及申請SSL證書流程詳解

京東云輕量云服務器與騰訊云域名結合配置網站及申請SSL證書流程詳解 1. 需求及實現效果 1.1. 需求 先說一下我當前情況&#xff0c;我目前有一個京東云服務器和一個在騰訊云旗下買的域名&#xff08;不要問為啥一個在京東云&#xff0c;一個在騰訊云&#xff0c;那自然是哪個…

Python入門Day14:面向對象編程初步(OOP入門)

學習目標&#xff1a;理解面向對象編程&#xff08;OOP&#xff09;的基本思想&#xff1a;類&#xff0c;對象掌握類的定義&#xff0c;構造方法&#xff0c;實例屬性和方法熟悉self的含義與作用學會用類組織和封裝代碼&#xff0c;初步構建自己的“對象世界”一、什么是面向對…

日志和指標標簽規范化方案

好的&#xff0c;設計一個有效的日志和指標標簽規范化方案對于構建可觀測性強、易于維護、關聯分析順暢的系統至關重要。混亂的標簽命名會極大增加查詢、聚合、告警和故障排除的難度。 以下是一個綜合性的標簽規范化方案建議&#xff0c;結合了行業最佳實踐&#xff1a; 核心目…

Windows和Linux的tree工具

目錄 1.前言 2.Linux的tree工具 2.1.安裝tree 2.2.常用命令與參數 2.3.常見應用場景 2.4.注意事項 3.Windows的tree工具 3.1.基礎語法 3.2.核心參數詳解 3.3.常見應用場景 3.4.局限性與增強方案 4.Windows 與 Linux tree 的核心差異 5.tree工具優勢 5.總結 相關…

[echarts] 更新數據

option {title: { text: 銷售數據 },tooltip: { trigger: axis },legend: { data: [銷量, 庫存] },xAxis: {type: category,data: [襯衫, 羊毛衫, 雪紡衫]},yAxis: { type: value },series: [{ name: 銷量, type: bar, data: [5, 20, 36] },{ name: 庫存, type: line, data: […

通過el-image實現點擊文字查看圖片,及其圖片列表

場景一&#xff1a;表格中有時候會有點擊文字查看圖片的功能&#xff08;因為表格的一個單元格不方便顯示多個圖片&#xff09;如下圖所示&#xff1a;對于這個需求&#xff0c;我們可以應對的方案是&#xff1a;在文字旁邊寫一個el-image圖默認顯示多張圖片中的第一張&#xf…

003 實習(前端jquery之輪播圖,學校網頁)

web前端,查詢官網:w3schoolHTML:負責網頁結構&#xff08;頁面元素和內容&#xff09;CSS:負責網頁的表現&#xff08;網頁元素的外觀、位置等頁面樣式&#xff0c;如顏色&#xff0c;大小&#xff09;JAVAScript:負責網頁的行為&#xff08;交互效果&#xff09;<a>:超鏈…

Mysql group by

臨時表與內存表 內存表是 Memory 引擎表&#xff0c;表的數據行都在內存。 臨時表可以使用各種引擎。 臨時表是線程私有表&#xff0c;其他線程不可見&#xff0c;不需考慮重名問題。 session 結束時臨時表會被自動刪除。 如果 Binlog_format row&#xff0c;則臨時表語句不進…

Linux(15)——進程間通信

目錄 一、進程間通信的介紹 ??進程間通信的目的 ??進程間通信的本質 進程間通信的分類 ??管道 ??System V IPC ??POSIX IPC 二、管道 &#x1f9e0;什么是管道 ??匿名管道 &#x1f4dd;匿名管道的原理 &#x1f4dd;pipe函數 &#x1f4dd;匿名管道…

【Flutter】雙路視頻播放方案

最近在做雙路視頻播放&#xff0c;就是在一個頁面播放兩個視頻。我遇到的問題就是音頻焦點沖突問題&#xff0c;在下面說明。什么是雙路視頻播放&#xff08;來自AI&#xff09;雙路視頻播放&#xff08;Dual-Video Playback&#xff09;&#xff0c;從字面上理解&#xff0c;就…

筆試——Day25

文章目錄第一題題目思路代碼第二題題目&#xff1a;思路代碼第三題題目&#xff1a;思路代碼第一題 題目 笨小猴 思路 模擬 統計每個字符出現的次數&#xff0c;用最大減最小&#xff0c;判斷是不是質數&#xff1b; 質數的判斷使用試除法&#xff1b; 代碼 第二題 題目&…

【C#學習Day15筆記】拆箱裝箱、 Equals與== 、文件讀取IO

前言在C#第15天的學習中&#xff0c;我深入探索了類型轉換機制、對象比較原理和文件操作技術三大核心主題。這些知識是構建高效、健壯程序的關鍵基礎。本文完整保留我的課堂實踐代碼和命名體系&#xff0c;通過結構化梳理幫助大家掌握這些核心概念。所有代碼示例均來自我的實際…

發電類電力業務許可證申請條件

基本條件&#xff1a;法人資格&#xff1a;申請人必須是依法注冊的企業法人。 財務能力&#xff1a;應具有與所申請從事的電力業務相適應的財務能力。 專業人員要求&#xff1a;生產運行負責人、技術負責人、安全負責人和財務負責人需具備至少3年以上與申請從事的電力業務相關的…

JavaScript 高效入門指南:從基礎到實戰(VSCode 版)

廢話不多說&#xff0c;直接上干貨&#x1f600; 一、先搞定工具&#xff1a;VSCode 配置成「JS 開發神器」 工欲善其事&#xff0c;必先利其器。用 VSCode 寫 JavaScript&#xff0c;這幾個配置能讓你效率翻倍&#xff1a; 1. 必裝插件&#xff08;直接在 VSCode 插件商店搜…

《人形機器人的覺醒:技術革命與碳基未來》——類人關節設計:柔性驅動革命之液壓人工肌肉

目錄&#xff1a;一、人工肌肉的種類及人形機器人適用情況二、人形機器人用人工肌肉科研機構及其最新成果進展三、液壓人工肌肉種類及工作機制四、液壓人工肌肉適用人形機器人的性能要求和局限性五、液壓人工肌肉材料技術進展及其限制與突破六、波士頓動力Spot的液壓靜液傳動系…