前端类的设计模式

134 阅读2分钟

1. 单例模式

单例模式是一种只允许创建一个实例的模式。在前端开发中,常用于创建全局唯一的对象,例如全局的状态管理器、日志记录器等。 单例模式可以保证全局只有一个实例,避免了重复创建和资源浪费的问题。

// 单例模式示例代码
class Singleton {
  constructor() {
    if (!Singleton.instance) {
      Singleton.instance = this;
    }
    return Singleton.instance;
  }

  createInstance() {
    const object = { name: "example" };
    return object;
  }

  getInstance() {
    if (!Singleton.instance) {
      Singleton.instance = this.createInstance();
    }
    return Singleton.instance;
  }
}

// 使用示例
const instance1 = new Singleton();
const instance2 = new Singleton();

console.log(instance1 === instance2); // true

2. 工厂模式

工厂模式是一种根据参数的不同创建不同对象的模式。常用于创建不同类型的组件、插件等。 工厂模式可以将对象的创建和使用分离,提高代码的灵活性和可维护性。

class Product {
  constructor(name) {
    this.name = name;
  }

  getName() {
    return this.name;
  }
}

class ProductFactory {
  static createProduct(name) {
    return new Product(name);
  }
}

// 使用示例
const product = ProductFactory.createProduct("Example Product");
console.log(product.getName()); // "Example Product"

3. 观察者模式

观察者模式是一种对象间的一对多依赖关系,当一个对象状态改变时,所有依赖它的对象都会自动更新。在前端开发中,常用于实现事件监听和消息订阅等。观察者模式可以降低对象间的耦合度,提高代码的可读性和可复用性。

class Subject {
  constructor() {
    this.observers = [];
  }

  addObserver(observer) {
    this.observers.push(observer);
  }

  removeObserver(observer) {
    const index = this.observers.indexOf(observer);
    if (index !== -1) {
      this.observers.splice(index, 1);
    }
  }

  notify(data) {
    this.observers.forEach(observer => observer.update(data));
  }
}

class Observer {
  update(data) {
    console.log(`Received data: ${data}`);
  }
}

// 使用示例
const subject = new Subject();
const observer1 = new Observer();
const observer2 = new Observer();

subject.addObserver(observer1);
subject.addObserver(observer2);

subject.notify("Hello World!");

4. 装饰器模式

装饰器模式是一种在不改变对象自身的基础上,动态地给对象增加新的功能的模式。 常用于实现组件的复用和功能的增强等。

interface Component {
  operation(): void;
}

class ConcreteComponent implements Component {
  public operation(): void {
    console.log("ConcreteComponent: operation.");
  }
}

class Decorator implements Component {
  protected component: Component;

  constructor(component: Component) {
    this.component = component;
  }

  public operation(): void {
    console.log("Decorator: operation.");
    this.component.operation();
  }
}

class ConcreteDecoratorA extends Decorator {
  public operation(): void {
    super.operation();
    console.log("ConcreteDecoratorA: operation.");
  }
}

class ConcreteDecoratorB extends Decorator {
  public operation(): void {
    super.operation();
    console.log("ConcreteDecoratorB: operation.");
  }
}

// 使用示例
const concreteComponent = new ConcreteComponent();
const concreteDecoratorA = new ConcreteDecoratorA(concreteComponent);
const concreteDecoratorB = new ConcreteDecoratorB(concreteDecoratorA);

concreteDecoratorB.operation();

5. 代理模式

代理模式是一种通过一个代理对象控制对目标对象的访问的模式。 常用于实现图片懒加载、数据缓存等。代理模式可以保护目标对象,控制其访问和使用,提高代码的安全性和可读性。

const target = {
  method() {
    console.log("Target method.");
  }
};

const proxy = new Proxy(target, {
  get(target, prop) {
    console.log(`Called ${prop} method.`);
    return target[prop];
  }
});

// 使用示例
proxy.method(); // "Called method method. Target method."

6. 适配器模式

适配器模式是一种将不同接口转换成统一接口的模式。 常用于实现不同浏览器的兼容、不同数据格式的转换等。

class Adaptee {
  specificRequest() {
    return "适配者中的业务代码被调用";
  }
}

class Target {
  constructor() {
    this.adaptee = new Adaptee();
  }

  request() {
    let info = this.adaptee.specificRequest();
    return `${info} - 转换器 - 适配器代码被调用`;
  }
}

// 使用示例
let target = new Target();
target.request(); // "适配者中的业务代码被调用 - 转换器 - 适配器代码被调用"

7. MVC模式

MVC模式是一种将应用程序分为三个部分:模型、视图和控制器。在前端开发中,常用于实现数据的管理、页面的渲染和交互的处理等。

class Model {
  constructor() {
    this.data = {
      name: "example",
      age: 18,
      gender: "male"
    };
  }

  setData(key, value) {
    this.data[key] = value;
  }

  getData() {
    return this.data;
  }
}

class View {
  constructor() {
    this.container = document.createElement("div");
  }

  render(data) {
    const { name, age, gender } = data;
    this.container.innerHTML = `
      <p>Name: ${name}</p>
      <p>Age: ${age}</p>
      <p>Gender: ${gender}</p>
    `;
    document.body.appendChild(this.container);
  }
}

class Controller {
  constructor(model, view) {
    this.model = model;
    this.view = view;
    this.view.render(this.model.getData());
  }

  setData(key, value) {
    this.model.setData(key, value);
    this.view.render(this.model.getData());
  }
}

// 使用示例
const model = new Model();
const view = new View();
const controller = new Controller(model, view);

controller.setData("age", 20);