TypeScript 设计模式 - 原型模式

56 阅读2分钟

原型模式

在 TypeScript 中,原型模式(Prototype Pattern)是一种创建型设计模式,它允许通过复制已有的实例来创建新对象,而不是通过直接实例化一个新的对象。原型模式通过克隆现有对象来创建新对象,这在需要大量相似对象的情况下,能够减少性能开销。

原型模式的核心概念:

  1. 原型对象:是现有对象的蓝图,其他对象可以通过它来创建新对象。
  2. 克隆方法:通过克隆现有对象来生成新对象,而不需要重新构造。

适用场景:

  • 当创建一个对象的成本很高时,通过复制现有对象来创建新对象比重新创建更有效率。
  • 当你需要大量相似对象时,可以通过原型模式避免重复创建相同的对象。

TypeScript 中的实现:

// 原型接口
interface Prototype {
  clone(): Prototype;
}

// 具体的原型类
class ConcretePrototypeA implements Prototype {
  private name: string;

  constructor(name: string) {
    this.name = name;
  }

  // 克隆方法
  clone(): Prototype {
    return new ConcretePrototypeA(this.name);
  }

  public getName(): string {
    return this.name;
  }
}

// 另一个具体的原型类
class ConcretePrototypeB implements Prototype {
  private id: number;

  constructor(id: number) {
    this.id = id;
  }

  // 克隆方法
  clone(): Prototype {
    return new ConcretePrototypeB(this.id);
  }

  public getId(): number {
    return this.id;
  }
}

// 使用原型模式
const originalA = new ConcretePrototypeA("Prototype A");
const cloneA = originalA.clone();
console.log(cloneA.getName()); // 输出: Prototype A

const originalB = new ConcretePrototypeB(123);
const cloneB = originalB.clone();
console.log(cloneB.getId()); // 输出: 123

解析:

  1. Prototype 接口:定义了一个 clone 方法,该方法用于克隆现有对象。
  2. ConcretePrototypeA 和 ConcretePrototypeB:这两个类实现了 Prototype 接口,并提供了 clone 方法,允许复制它们的实例。
  3. 克隆:在使用原型模式时,通过 clone 方法,可以复制现有对象的状态,从而生成一个新的对象。

优势:

  • 减少创建对象的成本:直接克隆现有对象而不是重新创建对象,节省了资源。
  • 灵活性:通过改变克隆方法,可以自由复制对象的不同状态。

注意事项:

  • 如果对象内部有引用类型的数据(如数组或对象),需要特别注意浅拷贝与深拷贝的区别。在深拷贝的情况下,克隆的对象和原对象的引用数据不会相互影响。
// 浅拷贝的情况
class ConcretePrototypeA implements Prototype {
  private name: string;
  private data: number[];

  constructor(name: string, data: number[]) {
    this.name = name;
    this.data = data;
  }

  clone(): Prototype {
    // 浅拷贝:直接复制引用类型的数据
    return new ConcretePrototypeA(this.name, this.data);
  }

  public getData(): number[] {
    return this.data;
  }
}

const original = new ConcretePrototypeA("Prototype A", [1, 2, 3]);
const cloned = original.clone();
cloned.getData().push(4);

console.log(original.getData()); // 输出: [1, 2, 3, 4],原对象的 `data` 被修改了

如果需要深拷贝,可以手动处理对象中引用类型的字段,确保每个字段都被正确复制。

小结:

原型模式在 TypeScript 中实现得很简洁,通过 clone 方法来复制对象,避免了重复创建相似对象的开销。它特别适用于需要频繁创建相似对象的场景。