JAVA设计模式之生成器模式

来源:互联网 发布:涿州网络兼职招聘网 编辑:程序博客网 时间:2024/06/05 08:09

1. 什么是生成器模式?

《Head First设计模式》中定义:封装一个产品的构造过程,并允许按步骤构造。


生成器模式(Builder Pattern)将一个复杂对象构建与它的表示分离,使得同样的构建过程可以创建不同的表示。生成器模式是对象创建型模式,又叫建造者模式


生成器模式针对的是复杂对象的创建。它可以将复杂对象的建造过程抽象出来,使这个抽象过程的不同实现方法可以构造不同表现(属性)的对象。


举个例子加深理解:

比如我们要去法拉利私人定制一款汽车,我们只需要向服务商提需求,然后服务商就会协调生产车间生产汽车。定制的汽车就是一个复杂的对象,其中包含空调系统、电子系统。动力系统等,而每一个子系统的生产都是复杂且非常耗时的。如果全部工作都交给一个车间来生产的话(传统创建对象),可能等我老了这个车还没造出来。如果将生产过程各自分工(创建过程抽象出来),然后由一个协调部门负责组装的话,这样汽车建造速度将大大提高,而且私人定制也比较容易(想怎么组装就怎么组装),装上普通动力系统的就是法拉利轿车,装上强劲动力系统就是法拉利跑车(不同的表现)。这个协调部门就是Director角色。

 

2. 角色

 

图片来源于网络

抽象建造者(Builder):可以是接口也可以是抽象类。为创建产品Product对象的各个组件指定抽象方法。一般有两类方法,一类是创建复杂对象的各个组件(buildPartA、buildPartB...)和另一类返回创建的复杂对象(getResult)。

具体建造者(ConcreteBuilder):Builder的具体实现类,可以有多个,每一个提供复杂对象各个组件的一种创建和装配方法,最终返回创建好的复杂对象。

产品角色(Product):它是被构建的复杂对象,包含多个组成部件,具体建造者创建该产品的内部表示并定义它的装配过程

指挥者角色(Director):Director负责安排复杂对象Product的建造次序。Director和Builder存在关联关系,通过construct方法调用Builder中的创建方法完成复杂对象的创建。客户端只需要和Director联系。

3. 优点

(1)客户端不需要知道复杂对象的创建细节,将对象和创建过程解耦,使相同的创建过程可以创建不同的对象。

(2)每一个具体建造者都相对独立,而与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的具体建造者,用户使用不同的具体建造者即可创建不同的产品对象。由于指挥者类针对抽象建造者编程,增加新的具体建造者无须修改原有代码,系统扩展方便,符合“开闭原则”。

(3)可以更加精细地控制产品的创建过程。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也更方便使用程序来控制创建过程。

4. 缺点

(1)使用生成器模式必须要求Product类具有相似的结构,如果差异性太大就无法使用该模式,因此具有一定的局限性。

(2)将创建过程抽象出来会造成类文件增加。

5. 使用场景

(1)要生成的产品对象有复杂的内部结构,包含多个成员属性。

(2)将创建过程分离开,使相同的创建过程能创建不同的产品对象。

(3)产品对象内部组件之间存在相互依赖,且组件创建具有一定的顺序。

6. 示例代码

(1)抽象建造者类

/** *抽象建造者  */public abstract class AbstractCarBuilder {//产品的引用protected Car car;public AbstractCarBuilder() {this.car=new Car();}public abstract void buildAcSystem();public abstract void buildPowerSystem();public abstract void buildElectronicSystem();public Car getCar(){return car;}}

 

(2)具体建造者类

/** * 普通汽车建造者 */public class LittleCarBuilder extends AbstractCarBuilder {@Overridepublic void buildAcSystem() {this.car.setAcSystem("海尔空调系统");}@Overridepublic void buildPowerSystem() {this.car.setPowerSystem("1.6自然吸气系统");}@Overridepublic void buildElectronicSystem() {this.car.setElectronicSystem("华为电子系统");}}/** * 跑车建造者 */public class SportsCarBuilder extends AbstractCarBuilder {@Overridepublic void buildAcSystem() {this.car.setAcSystem("格力空调系统");}@Overridepublic void buildPowerSystem() {this.car.setPowerSystem("4.0T涡轮增压系统");}@Overridepublic void buildElectronicSystem() {this.car.setElectronicSystem("西门子电子系统");}}

(3)产品类

/** *产品类 *其中可能存在许多创建过程比较复杂的其他对象  */public class Car {//空调系统组件(可以是一个对象)private String acSystem;//动力系统组件private String powerSystem;//电子系统组件private String electronicSystem;public String getAcSystem() {return acSystem;}public void setAcSystem(String acSystem) {this.acSystem = acSystem;}public String getPowerSystem() {return powerSystem;}public void setPowerSystem(String powerSystem) {this.powerSystem = powerSystem;}public String getElectronicSystem() {return electronicSystem;}public void setElectronicSystem(String electronicSystem) {this.electronicSystem = electronicSystem;}@Overridepublic String toString() {return "Car [acSystem=" + acSystem + ", powerSystem=" + powerSystem + ", electronicSystem=" + electronicSystem+ "]";}}

(4)指挥者类

/** *car建造指挥者  */public class CarDirector {private AbstractCarBuilder acb;public CarDirector(AbstractCarBuilder acb) {this.acb=acb;}public void setAcb(AbstractCarBuilder acb) {this.acb = acb;}public Car constructCar(){//此处可以规定组件创建顺序acb.buildAcSystem();acb.buildElectronicSystem();acb.buildPowerSystem();return acb.getCar();}}

(5)测试

public class Client {public static void main(String[] args) {CarDirector director=new CarDirector(new SportsCarBuilder());Car car1=director.constructCar();System.out.println(car1.toString());System.out.println("---------------");director.setAcb(new LittleCarBuilder());Car car2=director.constructCar();System.out.println(car2.toString());}}

(6)测试结果

Car [acSystem=格力空调系统, powerSystem=4.0T涡轮增压系统, electronicSystem=西门子电子系统]---------------Car [acSystem=海尔空调系统, powerSystem=1.6自然吸气系统, electronicSystem=华为电子系统]


7. 生成器模式和工厂模式的对比

 

图片来源于网络


【四川乐山程序员联盟,欢迎大家加群相互交流学习5 7 1 8 1 4 7 4 3】

原创粉丝点击