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

原型設計模式

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

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]刪除
最新教學 更多>
  • eval()vs. ast.literal_eval():對於用戶輸入,哪個Python函數更安全?
    eval()vs. ast.literal_eval():對於用戶輸入,哪個Python函數更安全?
    稱量()和ast.literal_eval()中的Python Security 在使用用戶輸入時,必須優先確保安全性。強大的python功能eval()通常是作為潛在解決方案而出現的,但擔心其潛在風險。本文深入研究了eval()和ast.literal_eval()之間的差異,突出顯示其安全性含義...
    程式設計 發佈於2025-07-13
  • 如何有效地轉換PHP中的時區?
    如何有效地轉換PHP中的時區?
    在PHP 利用dateTime對象和functions DateTime對象及其相應的功能別名為時區轉換提供方便的方法。例如: //定義用戶的時區 date_default_timezone_set('歐洲/倫敦'); //創建DateTime對象 $ dateTime = ne...
    程式設計 發佈於2025-07-13
  • 編譯器報錯“usr/bin/ld: cannot find -l”解決方法
    編譯器報錯“usr/bin/ld: cannot find -l”解決方法
    錯誤:“ usr/bin/ld:找不到-l “ 此錯誤表明鏈接器在鏈接您的可執行文件時無法找到指定的庫。為了解決此問題,我們將深入研究如何指定庫路徑並將鏈接引導到正確位置的詳細信息。 添加庫搜索路徑的一個可能的原因是,此錯誤是您的makefile中缺少庫搜索路徑。要解決它,您可以在鏈接器命令中添...
    程式設計 發佈於2025-07-13
  • 使用jQuery如何有效修改":after"偽元素的CSS屬性?
    使用jQuery如何有效修改":after"偽元素的CSS屬性?
    在jquery中了解偽元素的限制:訪問“ selector 嘗試修改“:”選擇器的CSS屬性時,您可能會遇到困難。 This is because pseudo-elements are not part of the DOM (Document Object Model) and are th...
    程式設計 發佈於2025-07-13
  • Async Void vs. Async Task在ASP.NET中:為什麼Async Void方法有時會拋出異常?
    Async Void vs. Async Task在ASP.NET中:為什麼Async Void方法有時會拋出異常?
    在ASP.NET async void void async void void void void void的設計無需返回asynchroncon而無需返回任務對象。他們在執行過程中增加未償還操作的計數,並在完成後減少。在某些情況下,這種行為可能是有益的,例如未期望或明確預期操作結果的火災和...
    程式設計 發佈於2025-07-13
  • 如何處理PHP文件系統功能中的UTF-8文件名?
    如何處理PHP文件系統功能中的UTF-8文件名?
    在PHP的Filesystem functions中處理UTF-8 FileNames 在使用PHP的MKDIR函數中含有UTF-8字符的文件很多flusf-8字符時,您可能會在Windows Explorer中遇到comploreer grounder grounder grounder gro...
    程式設計 發佈於2025-07-13
  • 如何從PHP中的Unicode字符串中有效地產生對URL友好的sl。
    如何從PHP中的Unicode字符串中有效地產生對URL友好的sl。
    為有效的slug生成首先,該函數用指定的分隔符替換所有非字母或數字字符。此步驟可確保slug遵守URL慣例。隨後,它採用ICONV函數將文本簡化為us-ascii兼容格式,從而允許更廣泛的字符集合兼容性。 接下來,該函數使用正則表達式刪除了不需要的字符,例如特殊字符和空格。此步驟可確保slug僅包...
    程式設計 發佈於2025-07-13
  • Java中假喚醒真的會發生嗎?
    Java中假喚醒真的會發生嗎?
    在Java中的浪費喚醒:真實性或神話? 在Java同步中偽裝喚醒的概念已經是討論的主題。儘管存在這種行為的潛力,但問題仍然存在:它們實際上是在實踐中發生的嗎? Linux的喚醒機制根據Wikipedia關於偽造喚醒的文章,linux實現了pthread_cond_wait()功能的Linux實現,...
    程式設計 發佈於2025-07-13
  • 如何在鼠標單擊時編程選擇DIV中的所有文本?
    如何在鼠標單擊時編程選擇DIV中的所有文本?
    在鼠標上選擇div文本單擊帶有文本內容,用戶如何使用單個鼠標單擊單擊div中的整個文本?這允許用戶輕鬆拖放所選的文本或直接複製它。 在單個鼠標上單擊的div元素中選擇文本,您可以使用以下Javascript函數: function selecttext(canduterid){ if(d...
    程式設計 發佈於2025-07-13
  • 哪種方法更有效地用於點 - 填點檢測:射線跟踪或matplotlib \的路徑contains_points?
    哪種方法更有效地用於點 - 填點檢測:射線跟踪或matplotlib \的路徑contains_points?
    在Python Matplotlib's path.contains_points FunctionMatplotlib's path.contains_points function employs a path object to represent the polygon.它...
    程式設計 發佈於2025-07-13
  • 找到最大計數時,如何解決mySQL中的“組函數\”錯誤的“無效使用”?
    找到最大計數時,如何解決mySQL中的“組函數\”錯誤的“無效使用”?
    如何在mySQL中使用mySql 檢索最大計數,您可能會遇到一個問題,您可能會在嘗試使用以下命令:理解錯誤正確找到由名稱列分組的值的最大計數,請使用以下修改後的查詢: 計數(*)為c 來自EMP1 按名稱組 c desc訂購 限制1 查詢說明 select語句提取名稱列和每個名稱...
    程式設計 發佈於2025-07-13
  • CSS強類型語言解析
    CSS強類型語言解析
    您可以通过其强度或弱输入的方式对编程语言进行分类的方式之一。在这里,“键入”意味着是否在编译时已知变量。一个例子是一个场景,将整数(1)添加到包含整数(“ 1”)的字符串: result = 1 "1";包含整数的字符串可能是由带有许多运动部件的复杂逻辑套件无意间生成的。它也可以是故意从单个真理...
    程式設計 發佈於2025-07-13
  • \“(1)vs.(;;):編譯器優化是否消除了性能差異?\”
    \“(1)vs.(;;):編譯器優化是否消除了性能差異?\”
    答案: 在大多數現代編譯器中,while(1)和(1)和(;;)之間沒有性能差異。編譯器: perl: 1 輸入 - > 2 2 NextState(Main 2 -E:1)V-> 3 9 Leaveloop VK/2-> A 3 toterloop(next-> 8 last-> 9 ...
    程式設計 發佈於2025-07-13
  • PHP SimpleXML解析帶命名空間冒號的XML方法
    PHP SimpleXML解析帶命名空間冒號的XML方法
    在php 很少,請使用該限制很大,很少有很高。例如:這種技術可確保可以通過遍歷XML樹和使用兒童()方法()方法的XML樹和切換名稱空間來訪問名稱空間內的元素。
    程式設計 發佈於2025-07-13
  • Java字符串非空且非null的有效檢查方法
    Java字符串非空且非null的有效檢查方法
    檢查字符串是否不是null而不是空的 if(str!= null && str.isementy())二手: if(str!= null && str.length()== 0) option 3:trim()。 isement(Isement() trim whitespace whites...
    程式設計 發佈於2025-07-13

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

Copyright© 2022 湘ICP备2022001581号-3