阿里云主机折上折
  • 微信号
您当前的位置:网站首页 > 设计模式的三大分类:创建型、结构型、行为型

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

作者:陈川 阅读数:30097人阅读 分类: JavaScript

设计模式是软件开发中解决常见问题的可复用方案,JavaScript作为一门灵活的语言,设计模式的应用尤为广泛。三大分类包括创建型、结构型和行为型,每种类型针对不同场景提供解决方案。

创建型模式

创建型模式关注对象的创建机制,通过控制对象的创建过程来提升代码的灵活性和可复用性。在JavaScript中,常见的创建型模式包括工厂模式、抽象工厂模式、单例模式、建造者模式和原型模式。

工厂模式

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

class Button {
  render() {
    return '<button>Click me</button>';
  }
}

class Input {
  render() {
    return '<input type="text" />';
  }
}

function createComponent(type) {
  switch (type) {
    case 'button':
      return new Button();
    case 'input':
      return new Input();
    default:
      throw new Error('Unknown component type');
  }
}

const button = createComponent('button');
console.log(button.render()); // <button>Click me</button>

单例模式

单例模式确保一个类只有一个实例,并提供全局访问点。这在管理全局状态时特别有用:

class Logger {
  constructor() {
    if (Logger.instance) {
      return Logger.instance;
    }
    this.logs = [];
    Logger.instance = this;
  }

  log(message) {
    this.logs.push(message);
    console.log(`LOG: ${message}`);
  }

  printLogCount() {
    console.log(`${this.logs.length} Logs`);
  }
}

const logger1 = new Logger();
const logger2 = new Logger();
logger1.log('First message');
logger2.log('Second message');
logger1.printLogCount(); // 2 Logs
console.log(logger1 === logger2); // true

原型模式

JavaScript本身基于原型继承,原型模式通过克隆现有对象来创建新对象:

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

const myCar = Object.create(carPrototype);
myCar.color = 'red';
console.log(myCar.wheels); // 4
myCar.start(); // Car started

结构型模式

结构型模式关注如何组合类和对象形成更大的结构,主要包括适配器模式、桥接模式、组合模式、装饰器模式、外观模式、享元模式和代理模式。

适配器模式

适配器模式使接口不兼容的对象能够协同工作。例如将旧API适配到新系统:

class OldCalculator {
  operations(a, b, operation) {
    switch (operation) {
      case 'add':
        return a + b;
      case 'sub':
        return a - b;
      default:
        return NaN;
    }
  }
}

class NewCalculator {
  add(a, b) {
    return a + b;
  }
  subtract(a, b) {
    return a - b;
  }
}

class CalculatorAdapter {
  constructor() {
    this.calculator = new NewCalculator();
  }

  operations(a, b, operation) {
    switch (operation) {
      case 'add':
        return this.calculator.add(a, b);
      case 'sub':
        return this.calculator.subtract(a, b);
      default:
        return NaN;
    }
  }
}

const oldCalc = new OldCalculator();
console.log(oldCalc.operations(5, 3, 'add')); // 8

const adapter = new CalculatorAdapter();
console.log(adapter.operations(5, 3, 'add')); // 8

装饰器模式

装饰器模式动态地给对象添加额外职责。在JavaScript中可以通过高阶函数实现:

function withLogging(fn) {
  return function(...args) {
    console.log(`Calling function with args: ${args}`);
    const result = fn.apply(this, args);
    console.log(`Function returned: ${result}`);
    return result;
  };
}

function add(a, b) {
  return a + b;
}

const loggedAdd = withLogging(add);
loggedAdd(2, 3);
// Calling function with args: 2,3
// Function returned: 5

代理模式

代理模式为其他对象提供一种代理以控制对这个对象的访问。例如实现图片懒加载:

class ImageProxy {
  constructor(src) {
    this.src = src;
    this.realImage = null;
  }

  display() {
    if (!this.realImage) {
      this.realImage = new RealImage(this.src);
      this.realImage.loadFromServer();
    }
    this.realImage.display();
  }
}

class RealImage {
  constructor(src) {
    this.src = src;
    this.image = null;
  }

  loadFromServer() {
    console.log(`Loading image from ${this.src}`);
    this.image = document.createElement('img');
    this.image.src = this.src;
  }

  display() {
    console.log(`Displaying image ${this.src}`);
    document.body.appendChild(this.image);
  }
}

const proxy = new ImageProxy('example.jpg');
// 图片尚未加载
proxy.display(); // 加载并显示图片

行为型模式

行为型模式关注对象之间的通信和职责分配,主要包括责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式和访问者模式。

观察者模式

观察者模式定义对象间的一对多依赖,当一个对象状态改变时,所有依赖它的对象都会得到通知:

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

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

  unsubscribe(observer) {
    this.observers = this.observers.filter(obs => obs !== observer);
  }

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

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

const subject = new Subject();
const observer1 = new Observer();
const observer2 = new Observer();

subject.subscribe(observer1);
subject.subscribe(observer2);

subject.notify('Hello observers!');
// Observer received data: Hello observers!
// Observer received data: Hello observers!

策略模式

策略模式定义一系列算法,将它们封装起来并使它们可以相互替换:

class PaymentStrategy {
  pay(amount) {
    throw new Error('Method not implemented');
  }
}

class CreditCardStrategy extends PaymentStrategy {
  pay(amount) {
    console.log(`Paying ${amount} using Credit Card`);
  }
}

class PayPalStrategy extends PaymentStrategy {
  pay(amount) {
    console.log(`Paying ${amount} using PayPal`);
  }
}

class ShoppingCart {
  constructor() {
    this.strategy = null;
    this.amount = 0;
  }

  setStrategy(strategy) {
    this.strategy = strategy;
  }

  checkout() {
    if (!this.strategy) {
      throw new Error('No payment strategy set');
    }
    this.strategy.pay(this.amount);
  }
}

const cart = new ShoppingCart();
cart.amount = 100;
cart.setStrategy(new CreditCardStrategy());
cart.checkout(); // Paying 100 using Credit Card

cart.setStrategy(new PayPalStrategy());
cart.checkout(); // Paying 100 using PayPal

状态模式

状态模式允许对象在内部状态改变时改变它的行为:

class TrafficLight {
  constructor() {
    this.states = [new RedLight(), new YellowLight(), new GreenLight()];
    this.current = this.states[0];
  }

  change() {
    const currentIndex = this.states.indexOf(this.current);
    this.current = this.states[(currentIndex + 1) % this.states.length];
  }

  sign() {
    return this.current.sign();
  }
}

class Light {
  constructor(color) {
    this.color = color;
  }

  sign() {
    return this.color;
  }
}

class RedLight extends Light {
  constructor() {
    super('red');
  }
}

class YellowLight extends Light {
  constructor() {
    super('yellow');
  }
}

class GreenLight extends Light {
  constructor() {
    super('green');
  }
}

const trafficLight = new TrafficLight();
console.log(trafficLight.sign()); // red
trafficLight.change();
console.log(trafficLight.sign()); // yellow
trafficLight.change();
console.log(trafficLight.sign()); // green
trafficLight.change();
console.log(trafficLight.sign()); // red

迭代器模式

迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部表示:

class MyIterator {
  constructor(collection) {
    this.collection = collection;
    this.index = 0;
  }

  next() {
    return this.collection[this.index++];
  }

  hasNext() {
    return this.index < this.collection.length;
  }
}

class MyCollection {
  constructor() {
    this.items = [];
  }

  addItem(item) {
    this.items.push(item);
  }

  getIterator() {
    return new MyIterator(this.items);
  }
}

const collection = new MyCollection();
collection.addItem('First');
collection.addItem('Second');
collection.addItem('Third');

const iterator = collection.getIterator();
while (iterator.hasNext()) {
  console.log(iterator.next());
}
// First
// Second
// Third

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

前端川

前端川,陈川的代码茶馆🍵,专治各种不服的Bug退散符💻,日常贩卖秃头警告级的开发心得🛠️,附赠一行代码笑十年的摸鱼宝典🐟,偶尔掉落咖啡杯里泡开的像素级浪漫☕。‌