」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 原型設計模式

原型設計模式

發佈於2024-11-07
瀏覽:190

Prototype Design Pattern

JavaScript 中的原型设计模式是一种创建模式,允许您通过克隆现有对象(“原型”)来创建新对象,而不是从头开始创建它们,这充当一个原型。这种模式特别适合 JavaScript,因为 JavaScript 本身是一种基于原型的语言,当对象创建成本高昂或当您想要创建与基本原型共享某些属性的对象时非常有用。

ES6 类让我们更容易理解对象的结构。使用extends简化了继承,但在ES6之前,使用prototype来继承和实现。这是理解这个概念的博客。

Ps:在 JavaScript 的原型设计模式中,没有像其他语言(例如 Java)那样的内置 clone() 方法。但是,您可以在原型或构造函数中手动实现clone()方法以提供类似的功能。

原型模式背后的想法是:

  1. 创建一个充当原型(蓝图)的对象。
  2. 通过复制该对象或将新实例链接到原型,使用该对象创建新实例。

原型模式的关键概念

原型:创建新对象的模板对象。
克隆:通过复制原型来创建新对象。
原型链:对象可以将行为委托给其原型

第 1 部分:基本形状类

class Shape {
  constructor(type = 'Generic Shape', color = 'White') {
    this.type = type;
    this.color = color;
  }

  getDetails() {
    return `Type: ${this.type}, Color: ${this.color}`;
  }

  // Clone method to create a new object with the same prototype
  clone() {
    return Object.create(this);  // Creates a new object that inherits from this prototype
  }
}

解释

用途:Shape 类充当基类或“原型”,可以继承圆形或矩形等特定形状。

clone() 方法:这是原型模式的关键部分。我们不是从头开始创建类的新实例,而是创建现有实例(或“原型”)的克隆。在本例中,Object.create(this) 创建一个与原始 Shape 共享相同原型的新对象。

第 2 部分:Circle 类

class Circle extends Shape {
  constructor(radius = 0, color = 'White') {
    super('Circle', color); // Calls the parent (Shape) constructor
    this.radius = radius;
  }

  getArea() {
    return Math.PI * this.radius * this.radius;
  }
}

解释
用途:Circle 类扩展了 Shape 类并表示特定类型的形状。

属性

  • radius: 圆的半径。
  • 构造函数中,super()函数调用了 Shape 类,传递“Circle”作为形状类型和颜色。

getArea() 方法:使用公式 π * radius^2 计算圆的面积。

第 3 部分:矩形类

class Rectangle extends Shape {
  constructor(width = 0, height = 0, color = 'White') {
    super('Rectangle', color);  // Calls the parent (Shape) constructor
    this.width = width;
    this.height = height;
  }

  getArea() {
    return this.width * this.height;
  }
}

解释

用途: Rectangle 类扩展了 Shape 类,表示另一种特定类型的形状(矩形)。

  • 与Circle类一样,Rectangle类使用super()调用父类Shape构造函数,指定这是一个“矩形”。
  • getArea() 方法:使用公式 width * height
  • 计算矩形的面积

第 4 部分:克隆和使用原型

const circlePrototype = new Circle();  // Create prototype
const myCircle = circlePrototype.clone();  // Clone the prototype
myCircle.radius = 5;
myCircle.color = 'Red';

const rectanglePrototype = new Rectangle();  // Create prototype
const myRectangle = rectanglePrototype.clone();  // Clone the prototype
myRectangle.width = 10;
myRectangle.height = 5;
myRectangle.color = 'Blue';

解释

在这里,我们不是使用 new 关键字从头开始创建 myCircle 和 myRectangle 对象,而是克隆原型。

克隆过程

  • 首先,我们创建原型实例(circlePrototype和矩形Prototype)。
  • 然后,我们使用clone()方法克隆这些原型,该方法创建继承自原型对象的新对象。

修改克隆实例:

  • 克隆后,我们修改克隆对象(myCircle 和 myRectangle)的属性(例如半径、宽度、高度、颜色)以满足我们的需求。
  • 这使我们能够轻松地从基本原型创建多个对象,仅修改必要的属性。

第 5 部分:输出

console.log(myCircle.getDetails()); // Output: Type: Circle, Color: Red
console.log(`Circle Area: ${myCircle.getArea()}`);  // Output: Circle Area: 78.54

console.log(myRectangle.getDetails()); // Output: Type: Rectangle, Color: Blue
console.log(`Rectangle Area: ${myRectangle.getArea()}`);  // Output: Rectangle Area: 50

解释

  • 我们使用从 Shape 类继承的 getDetails() 方法来打印 myCircle 和 myRectangle 的详细信息(类型和颜色)。
  • 我们还使用 getArea() 方法(特定于 Circle 和 Rectangle 类)来计算和显示每个形状的面积。

原型设计模式视角:

  • 原型创建:我们不是从头开始创建新的 Circle 和 Rectangle 对象,而是首先创建一个原型实例(circlePrototype 和矩形Prototype)。
  • 克隆:一旦原型存在,就使用clone()方法基于原型创建新对象。这就是原型模式的本质:通过复制现有对象(原型)来创建对象。

使用案例:

原型模式在以下情况下很有用:

  • 您需要通过克隆现有对象来创建新对象。
  • 您希望避免子类化并直接重用现有对象作为蓝图。
  • 当需要创建许多类似的对象时,创建成本高昂或复杂。通过使用原型,您可以简化流程并提高效率。

如果您已经做到了这一步?✨,请在下面发表评论并提出任何问题或想法。我很乐意听取您的意见并参与一些精彩的讨论!✨

版本聲明 本文轉載於:https://dev.to/srishtikprasad/prototype-design-pattern-4c2i?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • PHP 可以像 JavaScript 一樣將函數當作參數傳遞嗎?
    PHP 可以像 JavaScript 一樣將函數當作參數傳遞嗎?
    在 PHP 中將函數作為參數傳遞將函數作為資料元素進行操作是現代程式設計中常用的通用技術。一個這樣的例子是將函數作為參數傳遞,這是 5.3 之前的 PHP 版本中不容易使用的功能。現在,我們深入研究此功能,探索何時以及如何使用它。 問題: 函數可以在 PHP 中作為參數傳遞嗎,類似 JavaScri...
    程式設計 發佈於2024-11-07
  • 反思 GSoC 4
    反思 GSoC 4
    Achievements, Lessons, and Tips for Future Success An exciting summer has come to a close for stdlib with our first participation in Google Summer of...
    程式設計 發佈於2024-11-07
  • 在 Go 中如何將位元組數組轉換為有符號整數和浮點數?
    在 Go 中如何將位元組數組轉換為有符號整數和浮點數?
    Go 中將位元組數組轉換為有符號整數和浮點數在Go 中,二進位包提供了從[]byte轉換無符號整數的函數數組,例如binary.LittleEndian.Uint16()和binary.BigEndian.Uint32()。然而,有符號整數或浮點數沒有直接等價物。 缺少有符號整數轉換函數的原因缺少有...
    程式設計 發佈於2024-11-07
  • 如何修復 Java + MySQL UTF-8 編碼問題:為什麼我的特殊字元顯示為問號?
    如何修復 Java + MySQL UTF-8 編碼問題:為什麼我的特殊字元顯示為問號?
    Java MySQL UTF-8 編碼問題Java MySQL UTF-8 編碼問題您提到了使用Java 和MySQL 時經常遇到的問題,其中儲存了特殊字元作為問號(“?”)。當 MySQL 資料庫、表格和欄位設定為使用 UTF-8 字元編碼,但 JDBC 連線未正確配置時,就會發生此問題。 在您的...
    程式設計 發佈於2024-11-07
  • 令牌桶演算法:流量管理必備指南
    令牌桶演算法:流量管理必備指南
    令牌桶演算法是控製網路流量、確保公平頻寬使用和防止網路擁塞的流行機制。它的運作原理很簡單,即根據令牌可用性來調節資料傳輸,其中令牌代表發送一定量資料的權利。該演算法對於維護各種系統(包括網路、API 和雲端服務)中的流量至關重要,提供了一種在不造成資源過載的情況下管理流量的方法。 令牌桶演算法如...
    程式設計 發佈於2024-11-07
  • 如何為您的 Python 專案選擇最佳的 XML 函式庫?
    如何為您的 Python 專案選擇最佳的 XML 函式庫?
    Python 中的XML 創建:庫和方法綜合指南在Python 中建立XML 文件時,開發人員可以選擇各種庫選項處理。最受歡迎和最直接的選擇是 ElementTree API,它是 Python 標準庫自 2.5 版以來不可或缺的一部分。 ElementTree:高效率選項ElementTree 提...
    程式設計 發佈於2024-11-07
  • 如何使用多個欄位對 Java 中的物件清單進行排序?
    如何使用多個欄位對 Java 中的物件清單進行排序?
    Java 中具有多個字段的列表對象的自定義排序雖然基於一個字段對列表中的對象進行排序很簡單,但使用多個字段進行排序可能有點棘手。本文深入研究按多個欄位排序的問題,並探討 Java 中可用的各種解決方案。 問題考慮一個場景,其中您有一個包含三個欄位的「Report」物件清單:ReportKey、學號和...
    程式設計 發佈於2024-11-07
  • 如何使用遞歸從具有父類別的資料庫產生巢狀選單樹?
    如何使用遞歸從具有父類別的資料庫產生巢狀選單樹?
    選單樹產生的遞歸在您的情況下,您有一個資料庫結構,其中類別有一個「根」欄位指示其父類別。您想要的 HTML 輸出涉及表示類別層次結構的巢狀清單。為此,可以使用遞歸 PHP 函數。 這是一個範例函數:function recurse($categories, $parent = null, $leve...
    程式設計 發佈於2024-11-07
  • Array_column 函數可以用於物件陣列嗎?
    Array_column 函數可以用於物件陣列嗎?
    將 array_column 與物件陣列一起使用將 array_column 與物件陣列一起使用本題探討了將 array_column 函數與由物件組成的陣列一起使用的可行性。開發人員實作了 ArrayAccess 接口,但發現它沒有任何影響。 PHP 5$titles = array_map(fu...
    程式設計 發佈於2024-11-07
  • HashMap 實際應用:應對常見的 Java 面試挑戰
    HashMap 實際應用:應對常見的 Java 面試挑戰
    技术面试通常会提出一些问题来测试您对集合的理解,尤其是HashMaps。一个常见的挑战涉及计算列表中元素的出现次数。这个问题可以帮助面试官评估您有效处理数据聚合并避免NullPointerException等陷阱的能力。 如果您是 HashMap 新手,在深入研究本文之前,您可能需要查看我的破解...
    程式設計 發佈於2024-11-07
  • SQL中什麼情況下交易不會自動回滾?
    SQL中什麼情況下交易不會自動回滾?
    自動事務回滾問題圍繞著 START TRANSACTION 包含的 SQL 語句區塊中發生錯誤時交易的行為提交交易。 OP注意到,當COMMIT TRANSACTION語句之前遇到語法錯誤時,交易會自動回滾。 事務回溯機制不,交易不會回溯遇到錯誤立即回傳。然而,某些客戶端應用程式可能會採用特定的錯誤...
    程式設計 發佈於2024-11-07
  • 如何使用陣列函數將字串轉換為關聯數組?
    如何使用陣列函數將字串轉換為關聯數組?
    使用陣列函數將字串轉換為關聯數組在PHP 中,經常需要將包含鍵值對的字串轉換為關聯數組關聯數組。考慮像“1-350,9-390.99”這樣的字串,其中每個元素由連字符和逗號分隔。目標是建立一個關聯數組,其中每個元素中的第一個數字成為鍵,第二個數字成為值。 可以使用 PHP 的內建數組函數有效地實現此...
    程式設計 發佈於2024-11-07
  • 了解無衝突複製資料類型
    了解無衝突複製資料類型
    無衝突複製資料類型 (CRDT) 是一類資料結構,可在分散式系統中實現無縫協作和資料同步,從而實現無衝突的協作更新。 CRDT 旨在實現跨多個資料副本的最終一致性,確保即使更新獨立發生,所有副本也能收斂到相同狀態,而不需要複雜的衝突解決機制。 在這篇文章中,我們將深入研究 CRDT 是什麼,探索它...
    程式設計 發佈於2024-11-07
  • 如何在 PyQt 應用程式中正確利用 QThreads?
    如何在 PyQt 應用程式中正確利用 QThreads?
    在PyQt 應用程式中使用QThreads 的最佳實踐使用QThreads 允許在PyQt 應用程式中進行多執行緒處理,從而實現任務分離並提高反應能力。然而,理解適當的技術至關重要。 重新實作 Run 方法的不適當性如同參考部落格文章中所提到的,重新實作 run 方法是不是使用 QThreads 的...
    程式設計 發佈於2024-11-07
  • 輕鬆掌握雙向一對一關係:提升 Spring Data JPA 效率
    輕鬆掌握雙向一對一關係:提升 Spring Data JPA 效率
    释放双向一对一关系的力量 在本深入指南中,我们将探讨相互一对一关联、CRUD 操作的复杂性,以及在高效数据建模中mappedBy、@JsonManagedReference 和 @JsonBackReference 的作用。 理解相互的一对一关联 简化 CRUD 操作 mappedBy 的重要性 揭...
    程式設計 發佈於2024-11-07

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3