设计模式- 建造者模式

 

建造模式

介绍

该子标题中内容,来源菜鸟教程

意图

将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。

主要解决

主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。

何时使用

一些基本部件不会变,而其组合经常变化的时候。

如何解决

将变与不变分离开。

优点

  1. 建造者独立,易扩展。

  2. 便于控制细节风险。

缺点:

  1. 产品必须有共同点,范围有限制。

  2. 如内部变化复杂,会有很多的建造类。

使用场景

  1. 需要生成的对象具有复杂的内部结构。

  2. 需要生成的对象内部属性本身相互依赖。

注意事项

与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。

代码

模式角色和职责

产品对象

复杂的内部属性集合的bean。
本文的例子:Company和CompanyPersonnel对象

抽象构建类

主要用来对产品的属性进行构建
本文的例子:CompanyBuilder对象

具体的构建类

该类实现 【抽象构建类】 ,对产品中的属性进行具体的创建
本文的例子:ATestCompanyBuilder对象

导演类

对产品进行具体的组装。
【具体的构建类】指的是产品中的属性进行构建,
而该类是获取最终的产品对象
本文的例子:Director对象

场景

代码含义

没有复杂业务,简单代码展示,对一个公司和员工的 bean 进行构建。

代码展示

产品对象

公司对象

package com.builderpattern.vo;


import lombok.Data;


import java.util.List;


/**
 * @version v1.0
 * @Copyright(c): 2020-2020
 * @FileName: Company.java
 * @Description: 公司对象
 * @autho Admin
 * @date 2020/1/13 11:35
 */
@Data
public class Company {


    /**
     * 名称
     */
    private String name;


    /**
     * 公司统一社会信用代码(公司的唯一标识)
     */
    private String socialId;


    /**
     * 企业员工
     */
    private List companyPersonnelList;
}


公司员工对象

package com.builderpattern.vo;


import lombok.Data;


/**
 * @version v1.0
 * @Copyright(c): 2020-2020
 * @FileName: CompanyPersonnel.java
 * @Description:
 * @autho Admin
 * @date 2020/1/13 13:54
 */
@Data
public class CompanyPersonnel {


    /**
     * 员工姓名
     */
    private String name;


    /**
     * 员工编号
     */
    private String number;


    /**
     * 员工年龄
     */
    private Integer age;


    /**
     * 员工性别  0:男  1:女
     */
    private String sex;
}


抽象构建类

package com.builderpattern.build;


import com.builderpattern.vo.Company;
import com.builderpattern.vo.CompanyPersonnel;


import java.util.List;


/**
 * @version v1.0
 * @Copyright(c): 2020-2020
 * @FileName: CompanyBuilder.java
 * @Description:
 * @autho Admin
 * @date 2020/1/13 13:56
 */
public abstract class CompanyBuilder {
    //创建公司对象(产品)
    protected Company company = new Company();


    /**
     * 产品属性建造  公司名称 可以通过外部传入获取
     * @return
     */
    public abstract CompanyBuilder buildName(String name);


    /**
     * 产品属性建造  统一社会信用代码
     * @return
     */
    public abstract CompanyBuilder buildSocialId();


    /**
     * 产品属性建造  公司员工集合
     * @return
     */
    public abstract CompanyBuilder buildPersonnelList();


    /**
     * 提供一个方法,可以得到产品
     * @return
     */
    public Company getCompany(){
        return company;
    }
}

具体的构建类

package com.builderpattern.build;


import com.builderpattern.vo.CompanyPersonnel;
import org.apache.commons.lang3.RandomUtils;


import java.util.ArrayList;
import java.util.List;


/**
 * @version v1.0
 * @Copyright(c): 2020-2020
 * @FileName: ATestCompanyBuilder.java
 * @Description: A测试公司建造
 * @autho Admin
 * @date 2020/1/13 14:04
 */
public class ATestCompanyBuilder extends CompanyBuilder{


    public CompanyBuilder buildName(String name) {
        company.setName(name);
        return this;
    }


    public CompanyBuilder buildSocialId() {
        company.setSocialId("91123123213213211A");
        return this;
    }


    public CompanyBuilder buildPersonnelList() {
        ArrayList list = new ArrayList();
        for (int i = 0; i < 10; i++) {
            CompanyPersonnel companyPersonnel = new CompanyPersonnel();
            companyPersonnel.setAge(18+i);
            companyPersonnel.setName("测试员工"+(i+1));
            companyPersonnel.setNumber(String.valueOf(i+1));
            companyPersonnel.setSex(i%2==0?"0":"1");
            list.add(companyPersonnel);
        }
        company.setCompanyPersonnelList(list);
        return this;
    }


}


导演类

package com.builderpattern.director;


import com.builderpattern.build.CompanyBuilder;
import com.builderpattern.vo.Company;
import lombok.Data;


/**
 * @version v1.0
 * @Copyright(c): 2020-2020
 * @FileName: Director.java
 * @Description:
 * @autho Admin
 * @date 2020/1/13 14:19
 */
@Data
public class Director {
    //获取build的基类对象,可以通过有参构造传入
    private CompanyBuilder companyBuilder;


    public Director(CompanyBuilder companyBuilder){
        this.companyBuilder = companyBuilder;
    }


    //负责公司(产品)对象的创建
    public Company construct(String name){
        return companyBuilder.buildName(name)
                .buildPersonnelList()
                .buildSocialId()
                .getCompany();
    }
}

测试类

package com.builderpattern;


import com.builderpattern.build.ATestCompanyBuilder;
import com.builderpattern.build.CompanyBuilder;
import com.builderpattern.director.Director;
import com.builderpattern.vo.Company;


/**
 * @version v1.0
 * @Copyright(c): 2020-2020
 * @FileName: Test.java
 * @Description:
 * @autho Admin
 * @date 2020/1/13 14:23
 */
public class Test {
    public static void main(String[] args) {
        //创建建造者
        CompanyBuilder builder = new ATestCompanyBuilder();
        //通过Director统一组建,并获取产品
        Director director = new Director(builder);
        Company construct = director.construct("A测试公司");


        System.out.println(construct);
    }
}


测试结果

Company(name=A测试公司, socialId=91123123213213211A,
companyPersonnelList=
[CompanyPersonnel(name=测试员工1, number=1, age=18, sex=0),
CompanyPersonnel(name=测试员工2, number=2, age=19, sex=1),
CompanyPersonnel(name=测试员工3, number=3, age=20, sex=0),
CompanyPersonnel(name=测试员工4, number=4, age=21, sex=1),
CompanyPersonnel(name=测试员工5, number=5, age=22, sex=0),
CompanyPersonnel(name=测试员工6, number=6, age=23, sex=1),
CompanyPersonnel(name=测试员工7, number=7, age=24, sex=0),
CompanyPersonnel(name=测试员工8, number=8, age=25, sex=1),
CompanyPersonnel(name=测试员工9, number=9, age=26, sex=0),
CompanyPersonnel(name=测试员工10, number=10, age=27, sex=1)])

什么时候使用

本文产品中的成员变量比较少,如果在业务比较复杂,成员变量很多,需要的有参构造方法比较多(而且可能有的成员变量要使用,有的不要使用,很容易乱。使用 set 多了,也会乱),难以维护,就可以使用该模式

附:目录结构

设计模式- 建造者模式_第1张图片

有需要源码的,也可以扫描下方二维码,加我好友,私聊我

- END -

推荐阅读

● 抽象工厂模式

● 装饰者模式

● 工厂模式

● 命令模式-接收者与执行者解耦和

● hexo-详细搭建

 

你可能感兴趣的:(java,设计模式)