”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 原型设计模式

原型设计模式

发布于2024-11-07
浏览:112

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]删除
最新教程 更多>
  • 如何在 Java 中转义特殊字符以实现精确的正则表达式匹配?
    如何在 Java 中转义特殊字符以实现精确的正则表达式匹配?
    转义特殊字符以实现最佳正则表达式匹配使用正则表达式 (regex) 匹配文本时,转义某些特殊字符至关重要,以确保它们被解释为文字而不是元字符。在Java中,必须转义的特殊字符包括:。 [ ] { } ( ) \ < > * - = ! ? ^ $ |但是,需要注意一些例外情况:方括号 ([]) 内只...
    编程 发布于2024-11-07
  • 用 Java 构建旋转排序数组搜索:了解枢轴搜索和二分搜索
    用 Java 构建旋转排序数组搜索:了解枢轴搜索和二分搜索
    什么是旋转排序数组? 考虑一个排序数组,例如: [1, 2, 3, 4, 5, 6] 现在,如果这个数组在某个枢轴处旋转,比如在索引 3 处,它将变成: [4, 5, 6, 1, 2, 3] 请注意,数组仍然是排序的,但它被分为两部分。我们的目标是有效地在此类数组中搜索目标值。 ...
    编程 发布于2024-11-07
  • 在 � 中学习 Three.js
    在 � 中学习 Three.js
    I had the chance to dive into some web development where I wanted to add interactive 3D elements that could move and react to certain triggers. Natura...
    编程 发布于2024-11-07
  • 网站时间数据集
    网站时间数据集
    您好,我在kaggle上发现了一个网站使用时间的数据集,所以我想找到访问页面数与网站总时间之间的比率。 您可以在我的github中找到数据集和代码:https://github.com/victordalet/Kaggle_analysis/tree/feat/website_traffic ...
    编程 发布于2024-11-07
  • 简单异常示例
    简单异常示例
    该示例展示了如何监控和捕获异常。 尝试访问数组边界之外的索引会生成 ArrayIndexOutOfBoundsException。 程序故意引发此异常并捕获它。 要监视异常的代码放在 try 块内。 当发生异常时,抛出异常并被catch块捕获,结束try块。 控制权不是“叫”来捕捉的,而是自动转移...
    编程 发布于2024-11-07
  • 模板文字可以真正重用吗?
    模板文字可以真正重用吗?
    模板文字:复兴重用ES6 中的模板文字经常被吹捧为强大的文本操作工具,但一个棘手的问题仍然存在:它们真的可以重用吗?无法实现的期望乍一看,模板文字似乎只在声明时承诺动态替换。这就引出了一个问题:什么是保持静态的模板?打破循环与流行的看法相反,模板文字可以使用函数通过运行时替换来重新焕发活力构造函数作...
    编程 发布于2024-11-07
  • 在 Java 中使用 Fisher-Yates 算法对数组进行洗牌
    在 Java 中使用 Fisher-Yates 算法对数组进行洗牌
    介绍 在计算机科学领域,对元素数组或列表进行洗牌是一种常见的操作,可用于各种应用程序,从随机化游戏结果到分发牌组中的纸牌。为此目的最有效的算法之一是 Fisher-Yates Shuffle,也称为 Knuth Shuffle。该算法确保数组的每个排列都有相同的可能性,这使其成为创...
    编程 发布于2024-11-07
  • 我作为全栈开发人员的旅程:与 MERN Stack 一起成长的一年
    我作为全栈开发人员的旅程:与 MERN Stack 一起成长的一年
    你好!我是 Shivaji Zirpe,一位充满热情的全栈开发人员,专门研究 MERN 堆栈。在过去的一年里,我深入研究了 Web 开发领域,广泛使用了 React、Node.js、MongoDB 等。在这篇文章中,我想分享我的旅程、经历以及我作为开发人员的成长过程。 ?我的经历一览...
    编程 发布于2024-11-07
  • 什么是 FHIR?
    什么是 FHIR?
    介绍 与 fhir 相关的存储库列表 - Awesome-fhir 快速医疗保健互操作性资源 FHIR 服务器是一款强大的工具,彻底改变了医疗保健行业。 它充当访问和交换关键医疗数据的网关,实现不同系统和组织之间的无缝互操作性。 什么是 FHIR 服务器? FHI...
    编程 发布于2024-11-07
  • 为什么常量引用可以延长 C++ 中临时变量的生命周期?
    为什么常量引用可以延长 C++ 中临时变量的生命周期?
    通过常量引用扩展右值生命周期在 C 中,常量引用不仅充当不可变别名,还可以延长临时变量的生命周期。为什么 C 委员会决定实现此行为?此功能的一个基本原理是隐藏类和函数的实现细节。考虑一个可以返回行向量或列向量的矩阵类。为了优化性能,类可以选择根据其行优先或列优先组织返回对内部值的引用。通过要求客户端...
    编程 发布于2024-11-07
  • 如何在 Go 中将切片作为可变参数传递?
    如何在 Go 中将切片作为可变参数传递?
    将解压的切片作为可变参数传递在 Go 中,可变参数函数接受不定数量的特定类型的参数。将切片的切片传递给此类函数时,了解所涉及的类型转换和解包机制至关重要。如果切片包含与可变参数参数类型相同的元素,则可以在不使用切片的情况下传递切片拆包。然而,如果切片中包含多种类型的混合或切片中包含切片,则情况会变得...
    编程 发布于2024-11-07
  • 使用 TypeScript 和语义版本控制创建并发布 npm 库
    使用 TypeScript 和语义版本控制创建并发布 npm 库
    ?编写并发布最少的代码 要在 npm 上发布库,您需要: 一个npm 帐户;您可以在这里注册。 您的代码作为一个项目;即,您的代码目录中有一个 package.json,其中指定了名称和版本。请注意,您可以通过以下方式生成此文件: npm init 项目中的index.js。请记住...
    编程 发布于2024-11-07
  • 如何将包含的 PHP 脚本的值返回到主脚本?
    如何将包含的 PHP 脚本的值返回到主脚本?
    从包含的 PHP 脚本返回在 PHP 中,return() 函数通常用于退出脚本或函数。但是,它不能用于从包含的脚本返回到主脚本。要从包含的脚本返回并恢复主脚本中的执行,请考虑使用以下技术: 1.使用输出缓冲:在包含的脚本内,使用 ob_start() 将要返回的输出存储在变量中。然后,在主脚本中,...
    编程 发布于2024-11-07
  • samwise-CLI:开源 Terraform 模块依赖性跟踪器
    samwise-CLI:开源 Terraform 模块依赖性跟踪器
    地形 Terraform 是一种用 Hashicorp 配置语言 (HCL) 编写的基础设施即代码 (IaC) 工具。本文假设读者已经使用过 Terraform 并了解模块的工作原理。 在 Terraform 中编码的每个人都创建了自己的模块,或者至少使用了其他人的模块。 ...
    编程 发布于2024-11-07
  • CSS 鲜为人知但有用的功能
    CSS 鲜为人知但有用的功能
    CSS 有一些鲜为人知但有用的功能。我们将研究其中的一些。 1. CSS的scroll-snap-type属性和scroll-snap-stop属性 滚动快速停止 当为父元素下的每个子元素设置此属性时,当您快速滚动屏幕时,使用触控板或触摸屏快速滚动时将阻止下一个元素通...
    编程 发布于2024-11-07

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3