相关文章
设计模式 结构型
一、单例模式
单例模式(Singleton Pattern)是一种常见的创建型设计模式,它确保某个类只有一个实例,并提供一个全局访问点来获取该实例。单例模式通常用于那些需要全局唯一的对象,例如配置管理器、日志记录器、线程池等。
以下是单例模式的一种常见实现方式,即延迟加载和懒加载的线程安全单例模式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class Singleton { constructor() { if (!Singleton.instance) { Singleton.instance = this; } return Singleton.instance; }
static getInstance() { if (!Singleton.instance) { Singleton.instance = new Singleton(); } return Singleton.instance; } }
|
单例模式具有以下特点:
- 延迟加载:单例实例在第一次访问时才被创建,而不是在应用启动时就创建,这样可以避免不必要的内存占用和性能损耗。
- 线程安全:在多线程环境下,通过对 getInstance() 方法加锁,确保只有一个线程能够创建单例实例,从而避免了并发访问时可能导致的多个实例被创建的问题。
二、工厂方法模式
工厂方法模式(Factory Method Pattern)是一种创建型设计模式,它提供了一种将对象的实例化延迟到子类中进行的方式,从而使一个类的实例化过程能够在子类中进行定制化。工厂方法模式通过定义一个创建对象的接口,但允许子类决定要实例化的类是哪一个。这样可以将具体类的实例化逻辑推迟到子类中,使得系统更加灵活、可扩展和可维护。
工厂方法模式通常涉及以下角色:
- 抽象产品(Abstract Product):定义了产品对象的接口,是工厂方法模式所创建对象的父类,也可以是一个接口。
- 具体产品(Concrete Product):实现了抽象产品接口的具体对象。
- 抽象工厂(Abstract Factory):声明了工厂方法,返回一个抽象产品类型的对象。
- 具体工厂(Concrete Factory):实现了抽象工厂接口,负责实例化具体产品对象。
下面是一个简单的示例来说明工厂方法模式的使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| class Car { constructor() { this.type = 'Car'; }
drive() { console.log('Driving a car.'); } }
class BMW extends Car { constructor() { super(); this.brand = 'BMW'; } }
class Audi extends Car { constructor() { super(); this.brand = 'Audi'; } }
class CarFactory { createCar() { throw new Error('This method must be overridden.'); } }
class BMWFactory extends CarFactory { createCar() { return new BMW(); } }
class AudiFactory extends CarFactory { createCar() { return new Audi(); } }
const bmwFactory = new BMWFactory(); const audiFactory = new AudiFactory();
const myBMW = bmwFactory.createCar(); const myAudi = audiFactory.createCar();
myBMW.drive(); myAudi.drive();
|
在这个示例中,Car 是抽象产品,BMW 和 Audi 是具体产品。CarFactory 是抽象工厂,其中的 createCar() 方法是工厂方法。BMWFactory 和 AudiFactory 是具体工厂,它们分别负责实例化 BMW 和 Audi 对象。
工厂方法模式的优点包括:
- 符合开闭原则:可以轻松地添加新的产品和工厂而不需要修改现有的代码。
- 封装性良好:客户端代码只需要知道抽象工厂和抽象产品的接口,而不需要知道具体实现。
- 提高了系统的可扩展性:可以通过添加新的工厂来生产新的产品,而不需要修改现有代码。
三、抽象工厂模式
抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它提供了一种创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。抽象工厂模式是工厂方法模式的一种扩展,它在工厂方法模式的基础上提供了一种更高层次的抽象,允许客户端使用抽象工厂来创建一组产品。
代理模式通常涉及以下角色:
- 抽象产品(Abstract Product):定义了产品对象的接口,是一组相关或相互依赖的产品族的父类,也可以是一个接口。
- 具体产品(Concrete Product):实现了抽象产品接口的具体对象。
- 抽象工厂(Abstract Factory):声明了创建一组产品的抽象方法,每个抽象方法对应一个产品族。
- 具体工厂(Concrete Factory):实现了抽象工厂接口,负责实例化一组具体产品。
下面是一个简单的示例来说明抽象工厂模式的使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
| class Button { click() { throw new Error('This method must be overridden.'); } }
class WindowsButton extends Button { click() { console.log('Windows button clicked.'); } }
class MacButton extends Button { click() { console.log('Mac button clicked.'); } }
class Checkbox { check() { throw new Error('This method must be overridden.'); } }
class WindowsCheckbox extends Checkbox { check() { console.log('Windows checkbox checked.'); } }
class MacCheckbox extends Checkbox { check() { console.log('Mac checkbox checked.'); } }
class GUIFactory { createButton() { throw new Error('This method must be overridden.'); }
createCheckbox() { throw new Error('This method must be overridden.'); } }
class WindowsFactory extends GUIFactory { createButton() { return new WindowsButton(); }
createCheckbox() { return new WindowsCheckbox(); } }
class MacFactory extends GUIFactory { createButton() { return new MacButton(); }
createCheckbox() { return new MacCheckbox(); } }
function renderGUI(factory) { const button = factory.createButton(); const checkbox = factory.createCheckbox();
button.click(); checkbox.check(); }
renderGUI(new WindowsFactory()); renderGUI(new MacFactory());
|
在这个示例中,Button 和 Checkbox 是抽象产品,WindowsButton、MacButton、WindowsCheckbox 和 MacCheckbox 是具体产品。GUIFactory 是抽象工厂,其中的 createButton() 和 createCheckbox() 方法是工厂方法。WindowsFactory 和 MacFactory 是具体工厂,它们分别负责实例化 Windows 和 Mac 版本的按钮和复选框。
四、建造者模式
建造者模式(Builder Pattern)是一种创建型设计模式,它可以将一个复杂对象的构建过程和表示分离开来,使得同样的构建过程可以创建不同的表示。建造者模式将一个复杂对象的构建过程拆分为多个步骤,并提供一个指挥者(Director)来组织这些步骤,从而使得客户端可以根据需要选择和组合这些步骤,创建出不同的对象。
建造者模式通常涉及以下几个角色:
- 产品(Product):表示正在构建的复杂对象。产品类通常包含多个属性和方法,它是由具体建造者按照一定的构建步骤逐步构建而成的。
- 抽象建造者(Builder):定义了构建产品对象的接口,包括设置产品各个部件的方法。
- 具体建造者(Concrete Builder):实现了抽象建造者接口,负责构建产品的具体部件和组装过程。每个具体建造者对应一个特定的产品构建过程。
- 指挥者(Director):负责组织和指挥建造者构建产品的步骤,它通常包含一个构建方法,用于调用具体建造者的各个步骤来构建产品。
下面是一个简单的示例来说明建造者模式的使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
| class Car { constructor() { this.parts = []; }
addPart(part) { this.parts.push(part); }
showInfo() { console.log('Car parts:'); this.parts.forEach(part => { console.log(`- ${part}`); }); } }
class CarBuilder { constructor() { this.car = new Car(); }
addEngine() {}
addWheels() {}
addInterior() {}
getResult() { return this.car; } }
class SedanCarBuilder extends CarBuilder { addEngine() { this.car.addPart('Sedan Engine'); }
addWheels() { this.car.addPart('Sedan Wheels'); }
addInterior() { this.car.addPart('Sedan Interior'); } }
class SUVCarBuilder extends CarBuilder { addEngine() { this.car.addPart('SUV Engine'); }
addWheels() { this.car.addPart('SUV Wheels'); }
addInterior() { this.car.addPart('SUV Interior'); } }
class Director { constructor(builder) { this.builder = builder; }
construct() { this.builder.addEngine(); this.builder.addWheels(); this.builder.addInterior(); } }
const sedanBuilder = new SedanCarBuilder(); const suvBuilder = new SUVCarBuilder();
const sedanDirector = new Director(sedanBuilder); const suvDirector = new Director(suvBuilder);
sedanDirector.construct(); const sedanCar = sedanBuilder.getResult(); sedanCar.showInfo();
suvDirector.construct(); const suvCar = suvBuilder.getResult(); suvCar.showInfo();
|
在这个示例中,Car 是产品,CarBuilder 是抽象建造者,SedanCarBuilder 和 SUVCarBuilder 是具体建造者,Director 是指挥者。通过组合不同的具体建造者和指挥者,我们可以创建出不同类型的汽车。
五、原型模式
原型模式(Prototype Pattern)是一种创建型设计模式,它用于创建一个与当前对象相似的新对象,同时又能保持对象类型的一致性。原型模式通过克隆现有对象来创建新对象,而不是通过标准的构造函数来创建。这种方式可以避免频繁地使用构造函数来创建对象,提高了对象创建的效率。
下面是一个简单的示例来说明原型模式的使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| class Sheep { constructor(name, weight) { this.name = name; this.weight = weight; }
clone() { return new Sheep(this.name, this.weight); } }
const originalSheep = new Sheep('Dolly', 50); console.log(originalSheep);
const clonedSheep = originalSheep.clone(); console.log(clonedSheep);
|
在这个示例中,Sheep 是原型对象,它包含了一个 clone() 方法来克隆自身。当需要创建新的羊对象时,只需要调用原型对象的 clone() 方法即可。
原型模式的优点包括:
- 减少对象的创建时间:通过克隆现有对象来创建新对象,避免了频繁地使用构造函数来创建对象,提高了对象创建的效率。
- 简化对象的创建过程:客户端代码只需要调用原型对象的克隆方法,而不必了解具体对象的实现细节,使得对象创建的过程更加简单和灵活。