JavaScript设计模式是指在编写JavaScript代码时使用的一些通用的解决方案和最佳实践。这些设计模式可以帮助我们编写更可读、可维护、可复用、可扩展的代码,以及避免一些常见的编程错误。
以下是常用的JavaScript设计模式:
1. 单例模式(Singleton Pattern):确保一个类只有一个实例,并提供全局访问点。
2. 工厂模式(Factory Pattern):定义一个创建对象的接口,但让子类决定实例化哪个类。工厂方法让类把实例化推迟到子类。
3. 观察者模式(Observer Pattern):定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
4. 原型模式(Prototype Pattern):用于创建重复的对象,同时又能保证性能。通过克隆现有的对象来创建新的对象。
5. 策略模式(Strategy Pattern):定义一系列算法,把它们封装起来,并且使它们可以互相替换。策略模式让算法独立于使用它的客户端。
6. 装饰者模式(Decorator Pattern):动态地给一个对象添加一些额外的职责。就增加功能来说,装饰者模式比生成子类更为灵活。
1、单例模式
例子中,我们使用了一个自执行函数来创建一个单例。这个单例只有在第一次被创建时才会实例化,之后每次获取实例都会返回同一个实例。
const Singleton = (function() {
let instance;
function createInstance() {
const object = new Object({name: "example"});
return object;
}
return {
getInstance: function() {
if (!instance) {
instance = createInstance();
}
return instance;
}
}
})();
const instance1 = Singleton.getInstance();
const instance2 = Singleton.getInstance();
console.log(instance1 === instance2); // true
2、工厂模式
例子中,我们使用了一个工厂类来创建动物对象。这个工厂类可以根据传入的参数来创建不同类型的动物对象。
class AnimalFactory {
createAnimal(type) {
switch(type) {
case "cat":
return new Cat();
case "dog":
return new Dog();
default:
throw new Error("Invalid animal type");
}
}
}
class Cat {
constructor() {
this.type = "cat";
}
}
class Dog {
constructor() {
this.type = "dog";
}
}
const factory = new AnimalFactory();
const cat = factory.createAnimal("cat");
const dog = factory.createAnimal("dog");
console.log(cat.type); // "cat"
console.log(dog.type); // "dog"
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);
}
}
notifyObservers() {
for (let observer of this.observers) {
observer.update();
}
}
}
class Observer {
constructor(name, subject) {
this.name = name;
this.subject = subject;
this.subject.addObserver(this);
}
update() {
console.log(`${this.name} received update from subject`);
}
}
const subject = new Subject();
const observer1 = new Observer("Observer 1", subject);
const observer2 = new Observer("Observer 2", subject);
subject.notifyObservers();
4、原型模式
例子中,我们使用了原型模式来创建一个人的原型对象。之后,我们可以通过这个原型对象来创建多个人的实例。这些实例都会共享原型对象的
const personPrototype = {
name: "John",
age: 30,
greet() {
console.log(`Hi, my name is ${this.name} and I'm ${this.age} years old`);
}
};
const person1 = Object.create(personPrototype);
person1.greet(); // "Hi, my name is John and I'm 30 years old"
const person2 = Object.create(personPrototype);
person2.name = "Jane";
person2.age = 25;
person2.greet(); // "Hi, my name is Jane and I'm 25 years old"
`Object.create`是 JavaScript 中的一种方法,它允许您创建具有指定原型对象和属性的新对象。
5、策略模式
例子中,我们创建了一个计算器类和两个策略类:加法策略和减法策略。我们将这些策略封装在不同的类中,并且使它们之间可以互相替换。计算器类使用策略类来执行计算,并且可以在运行时更改策略。这种设计使得我们可以很容易地添加新的策略类,而不需要修改计算器类的代码。
class Calculator {
constructor(strategy) {
this.strategy = strategy;
}
setStrategy(strategy) {
this.strategy = strategy;
}
calculate(num1, num2) {
return this.strategy.calculate(num1, num2);
}
}
class AddStrategy {
calculate(num1, num2) {
return num1 + num2;
}
}
class SubtractStrategy {
calculate(num1, num2) {
return num1 - num2;
}
}
const calculator = new Calculator(new AddStrategy());
console.log(calculator.calculate(5, 3)); // 8
calculator.setStrategy(new SubtractStrategy());
console.log(calculator.calculate(5, 3)); // 2
5、装饰者模式
例子中,我们创建了一个汽车类和两个装饰者类:空调装饰者和皮座椅装饰者。我们将这些装饰者封装在不同的类中,并且使它们可以动态地添加到汽车对象中。每个装饰者都会修改
class Car {
constructor() {
this.price = 10000;
this.model = "Car";
}
getPrice() {
return this.price;
}
getDescription() {
return this.model;
}
}
class Decorator {
constructor(car) {
this.car = car;
}
getPrice() {
return this.car.getPrice();
}
getDescription() {
return this.car.getDescription();
}
}
class AirConditioner extends Decorator {
constructor(car) {
super(car);
this.price = 800;
this.model = car.getDescription() + ", with air conditioner";
}
getPrice() {
return this.car.getPrice() + this.price;
}
getDescription() {
return this.model;
}
}
class LeatherSeats extends Decorator {
constructor(car) {
super(car);
this.price = 1500;
this.model = car.getDescription() + ", with leather seats";
}
getPrice() {
return this.car.getPrice() + this.price;
}
getDescription() {
return this.model;
}
}
let car = new Car();
console.log(car.getDescription() + " costs $" + car.getPrice());
car = new AirConditioner(car);
console.log(car.getDescription() + " costs $" + car.getPrice());
car = new LeatherSeats(car);
console.log(car.getDescription() + " costs $" + car.getPrice());