返回
洞悉js设计模式(二):灵活构建,挥洒创意
前端
2023-10-13 16:28:19
创建型设计模式:对象创建的艺术
在软件工程中,创建型设计模式是一种处理对象创建的设计模式,它旨在根据实际情况使用合适的方式创建对象。创建型模式的主要思想是将对象创建的细节与对象的具体实现分离,以便创建对象时可以更灵活地应对需求变化。
四种创建型设计模式,各显其能
在JavaScript中,最常用的创建型设计模式包括:
-
抽象工厂模式 :通过提供一个接口来创建相关的对象,而无需指定它们的具体类型,使系统独立于产品创建过程。
-
建造者模式 :通过将复杂对象的构建与它的表示分离,使同一个构建过程可以创建不同的表示。
-
原型模式 :通过创建一个类的实例,然后使用该实例作为模板来创建新的对象,使新对象与该原型具有相同的属性和方法。
-
单例模式 :确保某一个类只有一个实例,并提供一个全局访问点来获取该实例。
1. 抽象工厂模式:统一管理,模块开发
抽象工厂模式旨在将产品族对象的创建与具体的实现代码分离,从而提高代码的可重用性和可维护性。它定义了一个抽象的工厂接口,该接口用于创建不同类型产品的对象。通过抽象工厂模式,我们可以轻松地切换不同类型的产品,而无需更改代码逻辑。
适用场景:
- 同时创建多种相关或相互依赖的产品。
- 需要在不暴露产品类的情况下控制产品创建过程。
- 提高代码的可重用性,实现不同产品间的解耦。
代码示例:
// 定义抽象工厂接口
interface IAbstractFactory {
createProductA(): ProductA;
createProductB(): ProductB;
}
// 定义具体工厂类,实现IAbstractFactory接口
class ConcreteFactory1 implements IAbstractFactory {
createProductA(): ProductA {
return new ProductA1();
}
createProductB(): ProductB {
return new ProductB1();
}
}
class ConcreteFactory2 implements IAbstractFactory {
createProductA(): ProductA {
return new ProductA2();
}
createProductB(): ProductB {
return new ProductB2();
}
}
// 定义产品类
class ProductA {
public operation(): string {
return "ProductA";
}
}
class ProductB {
public operation(): string {
return "ProductB";
}
}
// 定义具体产品类
class ProductA1 extends ProductA {}
class ProductA2 extends ProductA {}
class ProductB1 extends ProductB {}
class ProductB2 extends ProductB {}
// 使用抽象工厂创建产品
let factory: IAbstractFactory = new ConcreteFactory1();
let productA: ProductA = factory.createProductA();
let productB: ProductB = factory.createProductB();
console.log(productA.operation()); // 输出:ProductA
console.log(productB.operation()); // 输出:ProductB
2. 建造者模式:复杂构建,分而治之
建造者模式将复杂对象的构建与它的表示分离,使得同一个构建过程可以创建不同的表示。它将对象的创建过程封装在建造者对象中,从而使客户端代码与对象的具体构建过程分离。
适用场景:
- 需要创建复杂对象,且对象的各个组成部分可以独立创建。
- 需要创建具有不同表示形式的对象。
- 需要在不修改现有代码的情况下更改对象创建过程。
代码示例:
// 定义建造者接口
interface IBuilder {
buildPartA(): void;
buildPartB(): void;
buildPartC(): void;
getResult(): Product;
}
// 定义具体建造者类,实现IBuilder接口
class ConcreteBuilder1 implements IBuilder {
private product: Product = new Product();
buildPartA(): void {
this.product.add("PartA1");
}
buildPartB(): void {
this.product.add("PartB1");
}
buildPartC(): void {
this.product.add("PartC1");
}
getResult(): Product {
return this.product;
}
}
class ConcreteBuilder2 implements IBuilder {
private product: Product = new Product();
buildPartA(): void {
this.product.add("PartA2");
}
buildPartB(): void {
this.product.add("PartB2");
}
buildPartC(): void {
this.product.add("PartC2");
}
getResult(): Product {
return this.product;
}
}
// 定义产品类
class Product {
private parts: string[] = [];
public add(part: string): void {
this.parts.push(part);
}
public listParts(): void {
console.log("Product parts: " + this.parts.join(", "));
}
}
// 定义指挥者类
class Director {
private builder: IBuilder;
constructor(builder: IBuilder) {
this.builder = builder;
}
construct(): Product {
this.builder.buildPartA();
this.builder.buildPartB();
this.builder.buildPartC();
return this.builder.getResult();
}
}
// 使用建造者和指挥者创建产品
let builder1: IBuilder = new ConcreteBuilder1();
let director: Director = new Director(builder1);
let product1: Product = director.construct();
let builder2: IBuilder = new ConcreteBuilder2();
let director2: Director = new Director(builder2);
let product2: Product = director2.construct();
product1.listParts(); // 输出:Product parts: PartA1, PartB1, PartC1
product2.listParts(); // 输出:Product parts: PartA2, PartB2, PartC2
3. 原型模式:克隆对象,节省开销
原型模式通过创建一个类的实例,然后使用该实例作为模板来创建新的对象,使新对象与该原型具有相同的属性和方法。这种模式可以避免重复创建对象,从而提高性能。
适用场景:
- 需要创建大量相同或相似的对象。
- 需要在运行时创建对象,而无需指定具体类。
- 需要创建具有复杂初始化过程的对象。
代码示例:
// 定义原型类
class Prototype {
public cloned(): Prototype {
return new Prototype();
}
}
// 定义具体原型类,实现Prototype接口
class ConcretePrototype extends Prototype {
private field1: string;
private field2: number;
constructor(field1: string, field2: number) {
this.field1 = field1;
this.field2 = field2;
}
public cloned(): ConcretePrototype {
return new ConcretePrototype(this.field1, this.field2);
}
public operation(): void {
console.log(`Field1: ${this.field1}, Field2: ${this.field2}`);
}
}
// 使用原型创建新的对象
let prototype: Prototype = new ConcretePrototype("field1 value", 123);
let clone1: Prototype = prototype.cloned();
let clone2: Prototype = prototype.cloned();
prototype.operation(); // 输出:Field1: field1 value, Field2: 123
clone1.operation(); // 输出:Field1: field1 value, Field2: 123
clone2.operation(); // 输出:Field1: field1 value, Field2: 123
4. 单例模式:独一无二,掌控全局
单例模式旨在确保某一个类只有一个实例,并提供一个全局访问点来获取该实例。这种模式可以确保全局范围内只有一个对象,从而控制该对象的创建和使用。
适用场景:
- 需要创建一个全局可访问的对象,且该对象只允许有一个实例。
- 需要控制对象创建的时机和方式。
- 需要确保对象在整个应用程序中保持一致性。
代码示例:
// 定义单例类
class Singleton {
private static instance: Singleton;
private constructor() {}
public static getInstance(): Singleton {
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance