工厂方法模式

工厂方法模式是一种设计模式,它提供了一种方法来创建对象,而无需指定构造函数的类型。 在工厂方法模式中,使用一个专门的工厂类来创建所需的对象。 在抽象工厂类中定义了一个抽象工厂方法,该方法返回一个抽象产品类型。 具体工厂类继承抽象工厂类,并实现抽象工厂方法。 这样,在具体工厂类中就可以创建具体的产品对象。

例1

举个例子,假设我们有一个抽象产品类型为 Shape,并有两个具体产品,即 CircleSquare。 如果我们使用工厂方法模式来创建这些产品,那么我们可能会定义如下代码:

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
// 抽象产品类
abstract class Shape {
abstract draw(): void;
}

// 具体产品类 1
class Circle extends Shape {
draw() {
// 实现画圆的逻辑
}
}

// 具体产品类 2
class Square extends Shape {
draw() {
// 实现画正方形的逻辑
}
}

// 抽象工厂类
abstract class ShapeFactory {
abstract createShape(): Shape;
}

// 具体工厂类 1
class CircleFactory extends ShapeFactory {
createShape(): Shape {
return new Circle();
}
}

// 具体工厂类 2
class SquareFactory extends ShapeFactory {
createShape(): Shape {
return new Square();
}
}

工厂方法模式是一种非常有用的设计模式,它可以让我们在不指定构造函数的类型的情况下创建对象。 它可以使代码更加灵活,并且可以轻松地更改或扩展应用程序的对象创建方式。

实际上,也就是说,工厂方法不直接使用构造函数,而是使用一个工厂类,这个工厂类是和构造函数解耦。
这样,我们就可以在不指定具体的构造函数类型的情况下创建对象。 这使得代码更加灵活,并且可以轻松地更改或扩展应用程序的对象创建方式。

例子2

假设我们正在开发一个游戏,其中玩家可以使用多种武器进行战斗。 我们可以使用工厂方法模式来实现这个功能。

首先,我们可以定义一个抽象产品类型 Weapon,其中包含了武器的抽象方法 use()。 我们还可以定义几个具体产品类型,如 SwordBow,它们分别代表剑和弓。 接下来,我们可以定义一个抽象工厂类型 WeaponFactory,其中包含了一个抽象工厂方法 createWeapon(),该方法返回一个 Weapon 类型的对象。 最后,我们可以定义两个具体工厂类型,如 SwordFactoryBowFactory,它们分别继承了 WeaponFactory 类型,并实现了 createWeapon() 方法。

首先,我们定义抽象产品类型 Weapon:

1
2
3
abstract class Weapon {
abstract use(): void;
}

然后,我们定义具体产品类型 Sword 和 Bow:

1
2
3
4
5
6
7
8
9
10
11
class Sword extends Weapon {
use() {
console.log("Swinging sword!");
}
}

class Bow extends Weapon {
use() {
console.log("Shooting arrow!");
}
}

接下来,我们定义抽象工厂类型 WeaponFactory:

1
2
3
abstract class WeaponFactory {
abstract createWeapon(): Weapon;
}

最后,我们定义具体工厂类型 SwordFactory 和 BowFactory:

1
2
3
4
5
6
7
8
9
10
11
class SwordFactory extends WeaponFactory {
createWeapon() {
return new Sword();
}
}

class BowFactory extends WeaponFactory {
createWeapon() {
return new Bow();
}
}

现在,我们可以使用这些类来创建武器。例如,我们可以这样创建一把剑:

1
2
3
const swordFactory = new SwordFactory();
const sword = swordFactory.createWeapon();
sword.use(); // Output: "Swinging sword!"

我们也可以这样创建一张弓:

1
2
3
4
const bowFactory = new BowFactory();
const bow = bowFactory.createWeapon();
bow.use(); // Output: "Shooting arrow!"

工厂方法模式是一种创建型设计模式,它定义了一个创建对象的接口,但由子类决定实例化哪个类。工厂方法让类把实例化推迟到子类。

工厂方法模式的适用场景

工厂方法模式适用于以下场景:

  1. 当一个类不知道它所必须创建的对象的类的时候。
  2. 当一个类希望由它的子类来指定它所创建的对象的时候。
  3. 当类将创建对象的职责委托给多个帮助子类中的某一个,并且希望将哪一个帮助子类是代理者这一信息局部化的时候。

例如:
当你要创建一个电商网站,希望用户在结算时有多种支付方式可供选择,但是你不确定用户会选择哪种支付方式。这时候,你可以使用工厂方法模式来解决这个问题。
你可以定义一个抽象的支付方式类,然后分别定义支付宝、微信、银行卡等具体的支付方式类,最后定义一个支付方式工厂类,负责根据用户的选择创建对应的支付方式实例。这样,用户在结算时只需要选择想要使用的支付方式,工厂方法就会帮助你创建出对应的支付方式实例,而不需要关心具体的实现细节。

当你在开发一个聊天软件时,希望用户可以选择使用文本、语音、视频等不同的消息类型来聊天。这时候,你可以定义一个抽象的消息类,然后分别定义文本消息、语音消息、视频消息等具体的消息类,最后定义一个消息工厂类,负责根据用户的选择创建对应的消息实例。这样,用户在聊天时只需要选择想要发送的消息类型,工厂方法就会帮助你创建出对应的消息实例,而不需要关心具体的实现细节。

当你在开发一个图像处理软件时,希望用户可以选择使用不同的图像处理算法来处理图像。这时候,你可以定义一个抽象的图像处理类,然后分别定义黑白化、灰度化、锐化等具体的图像处理类,最后定义一个图像处理工厂类,负责根据用户的选择创建对应的图像处理实例。这样,用户在处理图像时只需要选择想要使用的图像处理算法,工厂方法就会帮助你创建出对应的图像处理实例,而不需要关心具体的实现细节。