您现在的位置是:网站首页 > 设计模式的三大分类:创建型、结构型、行为型文章详情

设计模式的三大分类:创建型、结构型、行为型

设计模式是软件开发中解决常见问题的可复用方案,JavaScript 作为一门灵活的语言,同样适用这些模式。按照目的和用途,设计模式分为创建型、结构型、行为型三大类,每类模式针对不同场景提供特定解决方案。

创建型模式

创建型模式关注对象的创建机制,抽象实例化过程,使系统与对象创建解耦。这类模式在 JavaScript 中尤为重要,因为语言本身没有类的概念(ES6 的 class 是语法糖)。

工厂模式

工厂模式通过一个公共接口创建对象,隐藏具体实现细节。例如一个 UI 组件库可能根据不同参数返回不同组件:

function createButton(type) {
  switch (type) {
    case 'primary':
      return new PrimaryButton();
    case 'danger':
      return new DangerButton();
    default:
      return new DefaultButton();
  }
}

单例模式

确保类只有一个实例,并提供全局访问点。前端常用在全局状态管理:

class Store {
  constructor() {
    if (!Store.instance) {
      this._state = {};
      Store.instance = this;
    }
    return Store.instance;
  }
}
const store1 = new Store();
const store2 = new Store();
console.log(store1 === store2); // true

建造者模式

分步骤构建复杂对象。例如构建一个包含多个配置选项的 HTTP 请求:

class RequestBuilder {
  constructor() {
    this.method = 'GET';
    this.headers = {};
  }
  
  setMethod(method) {
    this.method = method;
    return this;
  }
  
  setHeader(key, value) {
    this.headers[key] = value;
    return this;
  }
  
  build() {
    return new Request(this);
  }
}

结构型模式

结构型模式处理类和对象的组合,形成更大的结构。

适配器模式

使接口不兼容的对象能够协同工作。例如将老式回调 API 适配为 Promise:

function legacyApi(options, callback) {
  // 老式 API 实现
}

function modernApi(options) {
  return new Promise((resolve) => {
    legacyApi(options, (result) => resolve(result));
  });
}

装饰器模式

动态添加职责到对象。ES7 装饰器语法示例:

function readonly(target, key, descriptor) {
  descriptor.writable = false;
  return descriptor;
}

class User {
  @readonly
  name = 'default';
}

const user = new User();
user.name = 'new'; // TypeError: Cannot assign to read only property

外观模式

为复杂子系统提供简化接口。例如封装 DOM 操作:

const DOM = {
  get(id) {
    return document.getElementById(id);
  },
  
  hide(id) {
    this.get(id).style.display = 'none';
  },
  
  show(id) {
    this.get(id).style.display = 'block';
  }
};

行为型模式

行为型模式关注对象间的职责分配和算法抽象。

观察者模式

定义对象间的一对多依赖,当一个对象状态改变时,所有依赖者都会收到通知。实现一个简单的事件总线:

class EventBus {
  constructor() {
    this.listeners = {};
  }
  
  on(event, callback) {
    if (!this.listeners[event]) {
      this.listeners[event] = [];
    }
    this.listeners[event].push(callback);
  }
  
  emit(event, data) {
    (this.listeners[event] || []).forEach(cb => cb(data));
  }
}

策略模式

定义算法族,封装每个算法,使它们可以互相替换。表单验证场景:

const validators = {
  required(value) {
    return value.trim() !== '';
  },
  minLength(value, length) {
    return value.length >= length;
  }
};

function validate(formData, rules) {
  return rules.every(rule => validators[rule.validator](formData[rule.field], rule.param));
}

状态模式

允许对象在内部状态改变时改变其行为。实现一个简单的交通灯状态机:

class TrafficLight {
  constructor() {
    this.states = {
      red: { next: 'green', wait: 3000 },
      green: { next: 'yellow', wait: 2000 },
      yellow: { next: 'red', wait: 1000 }
    };
    this.current = this.states.red;
  }
  
  change() {
    setTimeout(() => {
      this.current = this.states[this.current.next];
      console.log(`Changed to ${this.current.next}`);
      this.change();
    }, this.current.wait);
  }
}

模式间的组合应用

实际开发中常组合使用多种模式。例如实现一个可撤销的命令系统:

// 命令模式 + 备忘录模式
class Editor {
  constructor() {
    this.content = '';
    this.history = [];
  }
  
  execute(command) {
    this.content = command.execute(this.content);
    this.history.push(command);
  }
  
  undo() {
    const command = this.history.pop();
    if (command) {
      this.content = command.undo(this.content);
    }
  }
}

class AddTextCommand {
  constructor(text) {
    this.text = text;
    this.previousText = '';
  }
  
  execute(content) {
    this.previousText = content;
    return content + this.text;
  }
  
  undo() {
    return this.previousText;
  }
}

JavaScript 特有的模式变体

由于 JavaScript 的动态特性,某些模式实现方式与传统面向对象语言不同:

原型模式

利用原型继承创建对象:

const carPrototype = {
  wheels: 4,
  start() {
    console.log('Engine started');
  }
};

const myCar = Object.create(carPrototype);
myCar.color = 'red';

模块模式

利用闭包创建私有成员:

const counter = (function() {
  let privateCount = 0;
  
  return {
    increment() {
      privateCount++;
    },
    get value() {
      return privateCount;
    }
  };
})();

我的名片

网名:~川~

岗位:console.log 调试员

坐标:重庆市-九龙坡区

邮箱:cc@qdcc.cn

沙漏人生

站点信息

  • 建站时间:2013/03/16
  • 本站运行
  • 文章数量
  • 总访问量
微信公众号
每次关注
都是向财富自由迈进的一步