-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
97 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
# 工厂模式 | ||
|
||
## 描述 | ||
|
||
工厂模式定义一个用于创建对象的接口,这个接口由子类决定实例化哪一个类。该模式使一个类的实例化延迟到了子类。而子类可以重写接口方法以便创建的时候指定自己的对象类型 | ||
|
||
## 模式结构 | ||
|
||
- `Factory`: 工厂角色,工厂角色负责实现创建所有实例的内部逻辑。 | ||
- `Product`: 抽象产品角色,抽象产品角色是所创建的所有对象的父类,负责描述所有实例所共有的公共接口。 | ||
- `ConcreteProduct`: 具体产品角色,具体产品角色是创建目标,所有创建的对象都充当这个角色的某个具体类的实例。 | ||
|
||
## 优点 | ||
|
||
- 工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅消费产品,简单工厂模式通过这种做法实现了对责任的分割,它提供了专门的工厂类用于创建对象。 | ||
- 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量。 | ||
- 通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。 | ||
|
||
## 缺点 | ||
|
||
- 添加新产品时,需要编写新的具体产品类,一定程度上增加了系统的复杂度 | ||
- 考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度 | ||
|
||
## 适用场景 | ||
|
||
- 如果你不想让某个子系统与较大的那个对象之间形成强耦合,而是想运行时从许多子系统中进行挑选的话,那么工厂模式是一个理想的选择 | ||
- 将new操作简单封装,遇到new的时候就应该考虑是否用工厂模式; | ||
- 需要依赖具体环境创建不同实例,这些实例都有相同的行为,这时候我们可以使用工厂模式,简化实现的过程,同时也可以减少每种对象所需的代码量,有利于消除对象间的耦合,提供更大的灵活性 | ||
|
||
```js | ||
// 工厂模式 | ||
|
||
// 基类 | ||
class Shape { | ||
say() { | ||
console.log(this.name); | ||
} | ||
} | ||
|
||
// 长方形 | ||
class Rectangle extends Shape { | ||
constructor() { | ||
super() | ||
this.name = 'Rectangle' | ||
} | ||
} | ||
|
||
// 正方形 | ||
class Square extends Shape { | ||
constructor() { | ||
super() | ||
this.name = 'Square' | ||
} | ||
} | ||
|
||
// 圆形 | ||
class Circle extends Shape { | ||
constructor() { | ||
super() | ||
this.name = 'Circle' | ||
} | ||
} | ||
|
||
// 工厂 | ||
class ShapeFactory { | ||
getShape(shapeType) { | ||
switch (shapeType.toLowerCase()) { | ||
case 'square': | ||
return new Square() | ||
case 'rectangle': | ||
return new Rectangle() | ||
case 'circle': | ||
return new Circle() | ||
default: | ||
throw new Error('参数错误') | ||
} | ||
} | ||
} | ||
|
||
const shapeFactory = new ShapeFactory() | ||
|
||
const rectangle = shapeFactory.getShape('rectangle') | ||
rectangle.say() | ||
|
||
const square = shapeFactory.getShape('square') | ||
square.say() | ||
|
||
const circle = shapeFactory.getShape('circle') | ||
circle.say() | ||
``` |