【设计模式】创建型

创建型设计模式

相关文章

设计模式 结构型


一、单例模式

单例模式(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(); // 输出 "Driving a car."
myAudi.drive(); // 输出 "Driving a car."

在这个示例中,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
// 抽象产品 A
class Button {
click() {
throw new Error('This method must be overridden.');
}
}

// 具体产品 A1
class WindowsButton extends Button {
click() {
console.log('Windows button clicked.');
}
}

// 具体产品 A2
class MacButton extends Button {
click() {
console.log('Mac button clicked.');
}
}

// 抽象产品 B
class Checkbox {
check() {
throw new Error('This method must be overridden.');
}
}

// 具体产品 B1
class WindowsCheckbox extends Checkbox {
check() {
console.log('Windows checkbox checked.');
}
}

// 具体产品 B2
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.');
}
}

// 具体工厂 1
class WindowsFactory extends GUIFactory {
createButton() {
return new WindowsButton();
}

createCheckbox() {
return new WindowsCheckbox();
}
}

// 具体工厂 2
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); // 输出: Sheep { name: 'Dolly', weight: 50 }

const clonedSheep = originalSheep.clone();
console.log(clonedSheep); // 输出: Sheep { name: 'Dolly', weight: 50 }

在这个示例中,Sheep 是原型对象,它包含了一个 clone() 方法来克隆自身。当需要创建新的羊对象时,只需要调用原型对象的 clone() 方法即可。

原型模式的优点包括:

  • 减少对象的创建时间:通过克隆现有对象来创建新对象,避免了频繁地使用构造函数来创建对象,提高了对象创建的效率。
  • 简化对象的创建过程:客户端代码只需要调用原型对象的克隆方法,而不必了解具体对象的实现细节,使得对象创建的过程更加简单和灵活。

喜欢这篇文章?打赏一下支持一下作者吧!
【设计模式】创建型
https://www.cccccl.com/20220807/设计模式/设计模式 创建型/
作者
Jeffrey
发布于
2022年8月7日
许可协议