一、模式定义
- 生成器模式又名建造模式,它可以将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象。
- 相关组件
- Builder:为创建一个Product对象的各个部件定义指定的抽象方法,并提供一个返回该Product的方法。
- ConcreteBuilder:实现Builder的接口以构造和装配该产品的各个部件。
- Director:导演类,用于指导具体构建者如何构建产品,控制调用先后次序,并向调用者返回完整的产品类。
- Product:表示被构造的复杂对象。包含定义组成部件的类,包括将这些部件装配成最终产品的接口。
二、举例说明
- 场景:当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时,可考虑使用生成器模式。
- 需求:豹女这个英雄有人形、狮形两种形态,使用R技能可切换形态;当豹女处于不同形态时,Q技能和W技能会表现为不同的行为。
三、代码实现
- 定义英雄类(产品)
public class Hero {
private String skillQ;
private String skillW;
private String skillE;
private String skillR;
// 省略getter/setter方法
}
- 抽象的builder类
public abstract class AbstractHeroBuilder {
protected Hero hero = new Hero();
public abstract void buildSkillQ();
public abstract void buildSkillW();
public abstract void buildSkillE();
public abstract void buildSkillR();
public Hero build() {
return hero;
}
}
- 两种英雄的builder实现
/**
* 瑞文的技能生成器
*
* @author: jsk
* @date: 2019/8/10 15:56
*/
public class RivenBuilder extends AbstractHeroBuilder {
@Override
public void buildSkillQ() {
hero.setSkillQ("Q技能:折翼之舞");
}
@Override
public void buildSkillW() {
hero.setSkillW("W技能:镇魂怒吼");
}
@Override
public void buildSkillE() {
hero.setSkillE("E技能:勇往直前");
}
@Override
public void buildSkillR() {
hero.setSkillR("R技能:放逐之锋");
}
}
/**
* 亚索的技能生成器
*
* @author: jsk
* @date: 2019/8/10 15:56
*/
public class YasuoBuilder extends AbstractHeroBuilder {
@Override
public void buildSkillQ() {
hero.setSkillQ("Q技能:斩钢闪");
}
@Override
public void buildSkillW() {
hero.setSkillW("W技能:风之障壁");
}
@Override
public void buildSkillE() {
hero.setSkillE("E技能:踏前斩");
}
@Override
public void buildSkillR() {
hero.setSkillR("R技能:狂风绝息斩");
}
}
- 定义技能指导类
public class SkillDirector {
private AbstractHeroBuilder heroBuilder;
public SkillDirector(AbstractHeroBuilder heroBuilder) {
this.heroBuilder = heroBuilder;
}
public Hero construct(){
heroBuilder.buildSkillQ();
heroBuilder.buildSkillW();
heroBuilder.buildSkillE();
heroBuilder.buildSkillR();
return heroBuilder.build();
}
}
- 客户端执行
public class HeroClient {
public static void main(String[] args) {
AbstractHeroBuilder rivenBuilder = new RivenBuilder();
AbstractHeroBuilder yasuoBuilder = new YasuoBuilder();
SkillDirector rivenSkillDirector = new SkillDirector(rivenBuilder);
Hero riven = rivenSkillDirector.construct();
System.out.println("瑞文的技能!");
System.out.println(riven.getSkillQ());
System.out.println(riven.getSkillW());
System.out.println(riven.getSkillE());
System.out.println(riven.getSkillR());
System.out.println("------------------------");
System.out.println("亚索的技能!");
SkillDirector yasuoSkillDirector = new SkillDirector(yasuoBuilder);
Hero yasuo = yasuoSkillDirector.construct();
System.out.println(yasuo.getSkillQ());
System.out.println(yasuo.getSkillW());
System.out.println(yasuo.getSkillE());
System.out.println(yasuo.getSkillR());
}
}
执行结果
四、扩展
若不是创建特别复杂的对象,可省略导演类(Director)并把builder作为Product中的一个内部静态类。其中,创建Builder的时候传入该Product的必要参数,其余扩展参数使用addXX()方法来传入;最后在提供一个build()方法来返回Product对象。
实现如下:
public class Product {
private String partA;
private String partB;
private String partC;
public Product(Builder builder) {
partA = builder.partA;
partB = builder.partB;
partC = builder.partC;
}
public static class Builder{
private String partA;
private String partB;
private String partC;
public Builder(String partA) {
this.partA = partA;
}
public Builder addPartB(String partB){
this.partB = partB;
return this;
}
public Builder addPartC(String partC){
this.partC = partC;
return this;
}
public Product build(){
return new Product(this);
}
}
}
// 创建方式
Product product = new Product.Builder("A")
.addPartB("B")
.addPartC("C")
.build();