建造者模式(builder pattern)
提到建造者,我们可能第一印象就是城市中建高楼大厦,建房子一般设计到业主,项目负责人,建筑队工人。业主告诉项目负责人,需要建造什么样的房子,项目负责人告诉工人应该怎么修建,不同工人完成不同工作。大家各司其职,最终得到一个建成的房子。虽然在建房子过程中,各个部分都需要打交道,但是更多的还是各司其职,每个人完成每个人的工作。其实就是把一个复杂的建房子工程,拆分成了若干部分由不同人来完成。在编程中也是如此,如果我们需要创建一个复杂的对象,可以把这个对象进行构建,使得不同部分,完成不同功能。
建造者模式定义:将一个复杂的对象分解成多个简单的对象来进行构建,将复杂的构建层与表示层分离,使得相同的构建过程可以创建不同的表示的模式便是建造者模式。看定义通常是无法直接理解这种设计模式的,还是直接看代码:
假设我们需要创建一辆车,车的组件包括车名,车牌号,车的价钱,车的引擎等。我们先看不使用建造者模式应该如何创建:
class Car{ constructor(){ this.name = ''; this.number = ''; this.price = ''; this.engine = ''; } //设置名字 setName(){ this.name = '宝马'; } //设置车牌号 setNumber(){ this.number = '888888' } //设置价钱 setPrice(){ this.price = '100万' } //设置引擎 setEngine(){ this.engine = '最好的引擎' } //车的创建 getCar(){ this.setName(); this.setNumber(); this.setPrice(); this.setEngine(); } } //创建一个车: let car = new Car(); car.getCar(); console.log(car)
从上面的代码中,我们可以看到创建一辆车需要的元素包括:name,number,price,engine。每一种元素又需要setxx来单独实现,最终车的创建还需要通过getCar来完成。也就是说在创建车的过程中需要的元素较多,创建过程相互影响,相互耦合。这只是简单的4个元素,而且耦合性也不是太高,但是假设元素他特别多,代码的耦合性也特别多,如果出现添加新的要素,那么实现起来要修改的代码就太多了。因此,我们需要对代码进行解耦,这就是建造者模式。
上面我们提到了建造一个房子,需要业主,项目负责人,建筑工人。其实建造者模式也包括这三个类:产品类(客户提出产品需要),指挥者类,建造者类。
建造者模式的使用流程如下:
- 客户提出产品需求:比如上面产品就是一辆小汽车,产品要素包括name,number,price,engine
- 指挥者根据产品需求,安排建造者完成需求的各个部分
- 建造者完成相应的部分
使用建造者模式修改上面的代码如下:
//产品类:产品要素 class Car{ constructor(){ this.name = ''; this.number = ''; this.price = ''; this.engine = ''; } } //建造者类:各种工人完成相应的部分 class CarBuilder{ setName(){ this.name = '宝马'; } setNumber(){ this.number = '888888'; } setPrice(price){ this.price = '100万'; } setEngine(engine){ this.engine = '最好的引擎'; } getCar(){ var car = new Car(); car.name = this.name; car.number = this.number; car.price = this.price; car.engine = this.engine; return car; } } //指挥官类:指挥工人完成各部分工作 class Director{ action(builder){ builder.setName(); builder.setNumber(); builder.setPrice(); builder.setEngine(); } } //使用方法: let builder = new CarBuilder(); let director = new Director(); director.action(builder); let car = builder.getCar(); console.log(car)
从上面的代码中,我们可以看出:定义了产品类,主要负责定义产品的需求;建造者类,主要负责完成需求的各个部分;指挥者类,主要负责指挥工人完成各部分工作。实际上就是把一辆车的复杂的创建过程抽离成三个简单的类来完成,大家各司其职,减少了代码的耦合。当以后需要添加新的需求时,只需要在各个部分单独定义即可,比如现在造汽车还需要安装玻璃,那么只需要在每个类里面定义玻璃相关的要素,建造者,指挥者即可。而不需要考虑代码的各部分耦合。这就是建造者模式。