蓦然回首,“工厂、构造、原型”设计模式,正在灯火阑珊处

简介: 蓦然回首,“工厂、构造、原型”设计模式,正在灯火阑珊处

很多工友们都说:设计模式根本用不到,然而它其实时刻就在我们身边,像王国维所说:众里寻他千百度,蓦然回首,那人正在灯火阑珊处。


本篇带来你一定熟知的、用于创建对象的三种设计模式:工厂模式、构造函数模式、原型模式;


image.png


工厂模式



什么是工厂模式?其实就字面意思,在现实社会生活中,市场通过不同工厂加工成不同的产品。


转化成 JS 代码就是这样的:

// 汽车工厂
function carFactory(brand, price, district) {
   let o = new Object();
   o.brand= brand;
   o.price= price;
   o.district= district;
   o.performance= function() {
     console.log(this.brand);
   };
   return o;
}
// 生产汽车
let car1 = carFactory("Benz", 50, "china");
let car2= carFactory("Honda", 30, "usa");
// 糖果工厂
function candyFactory(name, size, color) {
   let o = new Object();
   o.name= name;
   o.size= size;
   o.color= color;
   o.performance= function() {
     console.log(this.name);
   };
   return o;
}
// 生产糖果
let candy1= candyFactory("Oreo", "small", "white");
let candy2= candyFactory("quduoduo", "middle", "black");


有汽车工厂,糖果工厂等等,我们通过工厂函数,创建了特定对象。

工厂模式是一种众所周知的设计模式,广泛应用于软件工程领域,用于抽象创建特定对象的过程。


构造函数模式



构造函数是用于创建特定类型对象的,可以自定义构造函数,以函数的形式为自己的对象类型定义属性和方法。


比如前面的例子,就可以该写为:

// 构造汽车的构造函数
function Car(brand, price, district) {
   this.brand= brand;
   this.price= price;
   this.district= district;
   this.performance= function() {
     console.log(this.brand);
   };
}
// 构造汽车
let car1 = new Car("Benz", 50, "china");
let car2= new Car("Honda", 30, "usa");


与工厂模式的区别是,构造函数模式:

  1. 没有显式地创建对象;
  2. 属性和方法直接赋值给了 this;
  3. 没有 return;


构造函数首字母通常是大写;

这里涉及到一个重要的考点:即使用 new 会发生什么?


官方解答:

(1) 在内存中创建一个新对象。 (2) 这个新对象内部的[[Prototype]](隐式原型)特性被赋值为构造函数的 prototype (显示原型)属性。 (3) 构造函数内部的 this 被赋值为这个新对象(即 this 指向新对象)。 (4) 执行构造函数内部的代码(给新对象添加属性)。 (5) 如果构造函数返回非空对象,则返回该对象;否则,返回刚创建的新对象。

这个,就是“原型链”的构造过程!!


car1.__proto__===Car.prototype // true
car1 instanceof Car // true


  • 构造函数的问题

构造函数的主要问题在于,其定义的方法会在每个实例上都创建一遍。


什么意思?用代码来解释:


// 构造汽车的构造函数
function Car(brand, price, district) {
   this.brand= brand;
   this.price= price;
   this.district= district;
   this.performance= function() {
   };
}
// 构造汽车
let car1 = new Car("Benz", 50, "china");
let car2= new Car("Honda", 30, "usa");
car1.performance == car2.performance // false


即使是同样的方法,也不相等,因为每次执行 new 的时候,实例的方法都是重新创建的;


原型模式



原型模式可以解决构造函数模式“重复创建方法”的问题。


// 原型创建
function Car(brand, price, district) {
   Car.prototype.brand= brand;
   Car.prototype.price= price;
   Car.prototype.district= district;
   Car.prototype.performance= function() {
   };
}
let car1 = new Car("Benz", 50, "china");
let car2= new Car("Honda", 30, "usa");
car1.performance === car2.performance // true


这里不妨再重温一下原型链的指向关系:

car1.__proto__===Car.prototype // true
Car.__proto__===Function.prototype // true
Function.prototype.__proto__===Object.prototype //true
Car.prototype.__proto__===Object.prototype //true
Object.prototype.__proto__===null // true

原型模式弱化了向构造函数传递初始化参数的能力,会导致所有实例默认都取得相同的属性值。


function Person() {}
Person.prototype = {
 constructor: Person,
 friends: "A",
 sayName() {
 }
}; 
let person1 = new Person();
let person2 = new Person();
person1.friends="B";
person1.friends // 'B'
person2.friends // 'A'
function PersonArr() {}
PersonArr.prototype = {
 constructor: PersonArr,
 friends:["A"],
 sayName() {
 }
}; 
let person1 = new PersonArr();
let person2 = new PersonArr();
person1.friends.push("B");
person1.friends // ["A","B"]
person2.friends // ["A","B"]

原型上的所有属性是在实例间共享的,这对函数来说比较合适。对原始值的属性 也还好,但对于引用值的属性,则会产生混乱!!


小结:

工厂模式、构造函数模式、原型模式,这三者没有谁好谁坏,使用时,更多的是讲究一个 —— 适合!只有清楚它们的原理,才能游刃有余。


相关文章
|
3月前
|
设计模式 JavaScript 前端开发
从工厂到单例再到策略:Vue.js高效应用JavaScript设计模式
【8月更文挑战第30天】在现代Web开发中,结合使用JavaScript设计模式与框架如Vue.js能显著提升代码质量和项目的可维护性。本文探讨了常见JavaScript设计模式及其在Vue.js中的应用。通过具体示例介绍了工厂模式、单例模式和策略模式的应用场景及其实现方法。例如,工厂模式通过`NavFactory`根据用户角色动态创建不同的导航栏组件;单例模式则通过全局事件总线`eventBus`实现跨组件通信;策略模式用于处理不同的表单验证规则。这些设计模式的应用不仅提高了代码的复用性和灵活性,还增强了Vue应用的整体质量。
56 1
|
3月前
|
设计模式 XML 数据格式
python之工厂设计模式
python之工厂设计模式
python之工厂设计模式
|
3月前
|
设计模式 测试技术
依赖注入与工厂设计模式的区别
【8月更文挑战第22天】
62 0
|
5月前
|
设计模式 Java 编译器
设计模式——创建型模式(工厂,简单工厂,单例,建造者,原型)
设计模式——创建型模式(工厂,简单工厂,单例,建造者,原型)
|
4月前
|
设计模式 Java 开发者
工厂设计模式的实现与应用场景分析
工厂设计模式的实现与应用场景分析
|
6月前
|
设计模式
设计模式之工厂 Factory
设计模式之工厂 Factory
57 1
|
6月前
|
设计模式 存储 JavaScript
[设计模式Java实现附plantuml源码~创建型] 多态工厂的实现——工厂方法模式
[设计模式Java实现附plantuml源码~创建型] 多态工厂的实现——工厂方法模式
|
23天前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
|
2月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。
|
25天前
|
设计模式 开发者 Python
Python编程中的设计模式:工厂方法模式###
本文深入浅出地探讨了Python编程中的一种重要设计模式——工厂方法模式。通过具体案例和代码示例,我们将了解工厂方法模式的定义、应用场景、实现步骤以及其优势与潜在缺点。无论你是Python新手还是有经验的开发者,都能从本文中获得关于如何在实际项目中有效应用工厂方法模式的启发。 ###