1、为什么需要建造者模式
一般我们创建的都是简单对象,属性基本都是基本类型。而对于构建比如汽车,其又包含车轮、发动机、车身、底盘等多个部件,而对于车轮而言,车轮又有宽度、载重等一系列属性等等,此类的例子还有很多,比如组装电脑,其同样需要CPU、硬盘、内存条等等。针对这类比较复杂的对象,再通过简单的setter方法,就有些过于繁琐。这时候,建造者模式可以帮我们组装符合要求的比较复杂的对象。
2、建造者模式定义及几个角色
将客户端与包含多个组成部分的复杂对象的创建过程分离,返回给我们的是一个已经组装好的对象,客户端无需知道内部的构建,只需要所需要的构建者类型即可。
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
Product:(产品)
它是被构建的复杂对象,包含多个部件。
Builder:(抽象建造者)
它是创建一个产品Product对象的各个部件的抽象接口,在该接口中一般声明两类方法,一类是buildPartX(),用于构建各部件对象,另一类方法是construct(),用于组装各个部件,并返回复杂对象。该Builder类既可以是抽象类,也可以接口。
ConcreteBuilder:(具体建造者)
它是Builder(抽象建造者)的具体实现类,实现了Builder中的各个buildePartX()以及construct()方法,明确指定其建造的复杂对象,以及各个部件的装配。
Director: (指挥者)
指挥者,也可以看做导演,其具体安排复杂对象的构造次序,指挥者和抽象建造者之间有关联关系,可以在其construct()方法中调用建造者对象的部件构造与装配方法,完成复杂对象的创建。客户端一般只需要与指挥者进行交互,在客户端确定具体建造者的类型,并实例化具体建造者对象(也可以通过配置文件和反射机制),然后通过指挥者类的构造函数或者Setter方法将该对象传入指挥者类中。
3、建造者模式示例
Actor:具体的产品对象
import lombok.Data; @Data public class Actor { private String Type;//角色类型 private String sex;//性别 private String face;//脸型 private String constume;//服装 private String hairstyle;//发型 }
ActorBuilder:产品对象的抽象构建接口
public abstract class ActorBuilder { protected Actor actor = new Actor(); public abstract void buildType(); public abstract void buildSex(); public abstract void buildFace(); public abstract void buildConstume(); public abstract void buildHairType(); //工厂方法,返回一个完整的游戏角色对象 public Actor createActor(){ return actor; } }
HeroActorBuilder:英雄角色的具体构建者
public class HeroBuider extends ActorBuilder { @Override public void buildType() { actor.setType("英雄"); } @Override public void buildSex() { actor.setSex("男"); } @Override public void buildFace() { actor.setFace("英俊"); } @Override public void buildConstume() { actor.setConstume("盔甲"); } @Override public void buildHairType() { actor.setHairstyle("飘逸"); } }
ActorController:角色构建的指导者
public class ActorController { //逐步构建角色复杂产品对象 public Actor construct(ActorBuilder ab){ Actor actor; ab.buildType(); ab.buildSex(); ab.buildFace(); ab.buildConstume(); ab.buildHairType(); actor = ab.createActor(); return actor; } }
构建者模式测试
public class BuilderClient { public static void main(String[] args) { ActorController ac = new ActorController(); ActorBuilder ab = new HeroBuider(); Actor actor = ac.construct(ab); System.out.println(actor); } }
4、建造者模式优缺点
主要优点:
客户端无需关系复杂对象内部装配,产品和创建过程分离。
不同的建造者有不同的实现类,使用可以更加精细地控制产品的创建过程
符合“”开闭原则”
主要缺点:
建造者模式所创建的产品一般都拥有较多的共同点,组成部分相似,如果产品之间的差异性很大,不适合使用建造者模式。
内部过于复杂,定义很多具体构建者对象,导致系统庞大,增加系统维护成本。
5:适用场景
在以下情况下可以考虑使用建造者模式:
(1) 需要生成的产品对象有复杂的内部结构,这些产品对象通常包含多个成员属性。
(2) 需要生成的产品对象的属性相互依赖,需要指定其生成顺序。
(3) 对象的创建过程独立于创建该对象的类。在建造者模式中通过引入了指挥者类,将创建过程封装在指挥者类中,而不在建造者类和客户类中。
(4) 隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品。