【设计模式】01-一文理解常用设计模式-“创建型模式”篇
- 手机
- 2025-09-06 16:15:02

一、前言
最近在复习设计模式,撰写、整理了内容和代码片段,和大家一起交流学习。
设计模式是软件设计中常见问题的典型解决方案。
修改记录 更新内容更新时间第一版250212
更新了对文章中的模式代码示范的解释250214二、模式分类
模式可以根据其意图或目的来分类。常见的设计模式包括:
创建型模式提供创建对象的机制, 增加已有代码的灵活性和可复用性;
结构型模式介绍如何将对象和类组装成较大的结构, 并同时保持结构的灵活和高效;
行为型模式负责对象间的高效沟通和职责委派;
本篇文章介绍创建型模式,后续会更新其他两类设计模式。
三、创建型模式概述
创建型模式主要用于对象的创建过程,它隐藏了对象的创建逻辑,使得代码更具灵活性和可维护性。
四、常见创建型模式(配合代码) 1、单例模式(Singleton Pattern):确保一个类只有一个实例,并提供一个全局访问点来访问这个实例。
// 单例模式示例 const Singleton = (function () { let instance; function createInstance() { const object = new Object({ name: 'Singleton Object' }); return object; } return { getInstance: function () { if (!instance) { instance = createInstance(); } return instance; } }; }()); // 使用示例 const instance1 = Singleton.getInstance(); const instance2 = Singleton.getInstance(); console.log(instance1 === instance2); // 输出: true 代码分析 立即执行函数(IIFE): 代码使用了一个立即执行函数 (function () { ... }()),这样可以创建一个独立的作用域,避免变量和函数泄露到全局作用域。 instance 变量: 在立即执行函数内部声明了一个变量 instance,初始值为 undefined。这个变量用于存储单例对象的实例。 createInstance 函数: 该函数用于创建单例对象的实例。它使用 new Object() 创建一个新对象,并传入一个包含 name 属性的对象字面量 { name: 'Singleton Object' },最后返回这个新对象。 返回对象: 立即执行函数返回一个包含 getInstance 方法的对象。这个对象就是外部可以访问的接口。 getInstance 方法: 该方法是获取单例对象实例的唯一途径。首先检查 instance 是否为 undefined(即是否已经创建了实例)。如果 instance 为 undefined,则调用 createInstance 函数创建一个新的实例,并将其赋值给 instance。最后返回 instance。这样,无论调用多少次 getInstance 方法,只要 instance 已经被创建,就会一直返回同一个实例。代码运行结果
调用 Singleton.getInstance() 方法两次,分别将返回的实例存储在 instance1 和 instance2 中。使用 === 比较 instance1 和 instance2 是否为同一个对象。由于单例模式确保只有一个实例存在,所以 instance1 和 instance2 是同一个对象,比较结果为 true,并将结果打印到控制台。 2、工厂模式(Factory Pattern):定义一个创建对象的接口,让子类决定实例化哪个类。工厂方法使一个类的实例化延迟到其子类。
简单理解:工厂模式就像一个工厂,根据不同的需求生产不同的产品。你只需要告诉工厂你需要什么,工厂就会帮你创建出来。
// 工厂模式示例 function CarFactory() { this.createCar = function (type) { let car; if (type === 'sedan') { car = new Sedan(); } else if (type === 'suv') { car = new SUV(); } car.drive = function () { console.log(`Driving a ${this.constructor.name}`); }; return car; }; } //createCar 方法: //该方法接收一个 type 参数,用于指定要创建的汽车类型。 //根据 type 的值,使用 if-else 语句来决定创建哪种类型的汽车对象。如果 type 为 'sedan',则创建一个 Sedan 对象;如果 type 为 'suv',则创建一个 SUV 对象。 //为创建的汽车对象添加一个 drive 方法,该方法会在控制台打印出正在驾驶的汽车类型。这里使用 this.constructor.name 来获取汽车对象的构造函数名,从而得到汽车的类型。 //最后返回创建好的汽车对象。 function Sedan() { this.type = 'Sedan'; } //这是一个简单的构造函数,用于创建轿车对象。在创建 Sedan 对象时,会给对象添加一个 type 属性,值为 'Sedan'。 function SUV() { this.type = 'SUV'; } //意思同上 // 使用示例 const factory = new CarFactory(); const sedan = factory.createCar('sedan'); const suv = factory.createCar('suv'); sedan.drive(); // 输出: Driving a Sedan suv.drive(); // 输出: Driving a SUV代码运行结果
创建一个 CarFactory 类的实例 factory。调用 factory.createCar('sedan') 方法创建一个轿车对象,并将其赋值给 sedan。调用 factory.createCar('suv') 方法创建一个 SUV 对象,并将其赋值给 suv。分别调用 sedan.drive() 和 suv.drive() 方法,会在控制台输出相应的驾驶信息,表明成功创建并使用了不同类型的汽车对象。 3、抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
简单理解:就像一个超级工厂,能生产不同品牌的汽车系列产品。
// 抽象工厂模式示例 // 抽象工厂 function AbstractCarFactory() { this.createEngine = function () { throw new Error('This method must be overridden!'); }; this.createWheel = function () { throw new Error('This method must be overridden!'); }; } //功能:抽象工厂定义了创建发动机和车轮的抽象方法。由于这是抽象工厂,这些方法并没有具体实现,而是抛出一个错误,提醒具体工厂必须重写这些方法。 //作用:为具体工厂提供了一个统一的接口,确保所有具体工厂都实现了创建发动机和车轮的功能。 // 具体工厂:丰田工厂 function ToyotaFactory() { AbstractCarFactory.call(this); this.createEngine = function () { return new ToyotaEngine(); }; this.createWheel = function () { return new ToyotaWheel(); }; } //继承:使用 AbstractCarFactory.call(this) 继承了抽象工厂的属性和方法。 //方法实现:重写了 createEngine 方法,返回一个 ToyotaEngine 实例;重写了 createWheel 方法,返回一个 ToyotaWheel 实例。 // 具体工厂:本田工厂 function HondaFactory() { AbstractCarFactory.call(this); this.createEngine = function () { return new HondaEngine(); }; this.createWheel = function () { return new HondaWheel(); }; } //继承:同样继承了抽象工厂的属性和方法。 //方法实现:重写了 createEngine 方法,返回一个 HondaEngine 实例;重写了 createWheel 方法,返回一个 HondaWheel 实例。 // 丰田发动机 function ToyotaEngine() { this.start = function () { console.log('Toyota engine started'); }; } //功能:表示丰田发动机,有一个 start 方法,用于启动发动机并在控制台输出相应信息。 // 丰田车轮 function ToyotaWheel() { this.rotate = function () { console.log('Toyota wheel rotating'); //功能:表示丰田车轮,有一个 rotate 方法,用于模拟车轮转动并在控制台输出相应信息。}; } // 本田发动机 function HondaEngine() { this.start = function () { console.log('Honda engine started'); }; } //功能:表示本田发动机,有一个 start 方法,用于启动发动机并在控制台输出相应信息。 // 本田车轮 function HondaWheel() { this.rotate = function () { console.log('Honda wheel rotating'); }; } //功能:表示本田车轮,有一个 rotate 方法,用于模拟车轮转动并在控制台输出相应信息。 // 使用示例 const toyotaFactory = new ToyotaFactory(); const toyotaEngine = toyotaFactory.createEngine(); const toyotaWheel = toyotaFactory.createWheel(); toyotaEngine.start(); // 输出: Toyota engine started toyotaWheel.rotate(); // 输出: Toyota wheel rotating const hondaFactory = new HondaFactory(); const hondaEngine = hondaFactory.createEngine(); const hondaWheel = hondaFactory.createWheel(); hondaEngine.start(); // 输出: Honda engine started hondaWheel.rotate(); // 输出: Honda wheel rotating 代码运行结果 创建丰田工厂及部件:创建一个 ToyotaFactory 实例,使用该工厂创建丰田发动机和车轮,并调用它们的方法,输出相应信息。创建本田工厂及部件:创建一个 HondaFactory 实例,使用该工厂创建本田发动机和车轮,并调用它们的方法,输出相应信息。 4、建造者模式(Builder Pattern):将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。
简单理解:就像建造房子,有不同的建造步骤,最终可以建成不同风格的房子。
// 建造者模式示例 // 产品类:汽车 function Car() { this.wheels = null; this.engine = null; this.color = null; this.showInfo = function () { console.log(`Car with ${this.wheels} wheels, ${this.engine} engine and ${this.color} color`); }; } //属性: //wheels:用于存储汽车的车轮数量,初始值为 null。 //engine:用于存储汽车的发动机类型,初始值为 null。 //color:用于存储汽车的颜色,初始值为 null。 //方法: //showInfo:该方法会将汽车的车轮数量、发动机类型和颜色信息拼接成字符串,并打印到控制台,方便查看汽车的具体配置。 // 建造者类 function CarBuilder() { this.car = new Car(); this.setWheels = function (wheels) { this.car.wheels = wheels; return this; }; this.setEngine = function (engine) { this.car.engine = engine; return this; }; this.setColor = function (color) { this.car.color = color; return this; }; this.build = function () { return this.car; }; } //属性: //car:在构造函数中创建一个 Car 类的实例,后续的设置操作都是针对这个汽车对象进行的。 方法: //setWheels:接收一个 wheels 参数,将其赋值给 this.car.wheels,并返回 this(即当前 CarBuilder 实例),这样可以实现链式调用。 //setEngine:接收一个 engine 参数,将其赋值给 this.car.engine,同样返回 this 以支持链式调用。 //setColor:接收一个 color 参数,将其赋值给 this.car.color,也返回 this 用于链式调用。 //build:返回已经构建好的 this.car 对象,标志着汽车构建完成。 // 使用示例 const builder = new CarBuilder(); const car = builder .setWheels(4) .setEngine('V8') .setColor('Red') .build(); car.showInfo(); // 输出: Car with 4 wheels, V8 engine and Red color代码运行结果
创建一个 CarBuilder 类的实例 builder。通过链式调用 setWheels、setEngine 和 setColor 方法,依次为汽车设置车轮数量、发动机类型和颜色。调用 build 方法,得到最终构建好的 Car 对象,并将其赋值给 car。调用 car.showInfo() 方法,在控制台输出汽车的详细信息。 5、原型模式(Prototype Pattern):用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
简单理解:就像复印文件,有一个原始文件作为模板,然后可以复印出很多份一样的文件。
// 原型模式示例 const carPrototype = { brand: 'Unknown', model: 'Unknown', start: function () { console.log(`Starting the ${this.brand} ${this.model}`); }, clone: function () { const clone = Object.create(this); return clone; } }; //属性: //brand:初始值为 'Unknown',用于表示汽车的品牌。 //model:初始值为 'Unknown',用于表示汽车的型号。 //方法: //start:该方法会在控制台打印出启动当前汽车(根据 this.brand 和 this.model)的信息。这里的 this 指向调用该方法的对象。 //clone:使用 Object.create(this) 方法创建一个新对象,该新对象继承自当前原型对象(this)。这意味着新对象会拥有原型对象的所有属性和方法,并且对新对象属性的修改不会影响原型对象本身。最后返回这个克隆后的新对象。 // 使用示例 const car1 = carPrototype.clone(); car1.brand = 'Toyota'; car1.model = 'Corolla'; const car2 = carPrototype.clone(); car2.brand = 'Honda'; car2.model = 'Civic'; car1.start(); // 输出: Starting the Toyota Corolla car2.start(); // 输出: Starting the Honda Civic代码运行结果
创建 car1 对象: 调用 carPrototype.clone() 方法克隆原型对象,得到一个新的汽车对象 car1。分别为 car1 的 brand 和 model 属性赋值为 'Toyota' 和 'Corolla'。 创建 car2 对象: 同样调用 carPrototype.clone() 方法克隆原型对象,得到另一个新的汽车对象 car2。为 car2 的 brand 和 model 属性赋值为 'Honda' 和 'Civic'。 调用 start 方法: 分别调用 car1.start() 和 car2.start() 方法,由于 this 指向调用该方法的对象,所以会根据各自对象的 brand 和 model 属性输出相应的启动信息。五、小结
设计模式在编程当中还是挺重要的,优点包括但不限于:代码复用性更高、可维护性更强、可扩展性更好。
有时间可以花点时间学习/复习一下,相信对我们的编程技术和编程思维会有很多进步~
【设计模式】01-一文理解常用设计模式-“创建型模式”篇由讯客互联手机栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“【设计模式】01-一文理解常用设计模式-“创建型模式”篇”