前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >建造者模式

建造者模式

作者头像
杨小杰
发布2020-01-16 10:56:58
3980
发布2020-01-16 10:56:58
举报
文章被收录于专栏:JAVA知识总结与分享

建造模式

介绍

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

意图

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

主要解决

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

何时使用

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

如何解决

将变与不变分离开。

优点

  1. 建造者独立,易扩展。
  2. 便于控制细节风险。

缺点:

  1. 产品必须有共同点,范围有限制。
  2. 如内部变化复杂,会有很多的建造类。

使用场景

  1. 需要生成的对象具有复杂的内部结构。
  2. 需要生成的对象内部属性本身相互依赖。

注意事项

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

代码

模式角色和职责

产品对象
代码语言:javascript
复制
复杂的内部属性集合的bean。
本文的例子:Company和CompanyPersonnel对象
抽象构建类
代码语言:javascript
复制
主要用来对产品的属性进行构建
本文的例子:CompanyBuilder对象
具体的构建类
代码语言:javascript
复制
该类实现 【抽象构建类】 ,对产品中的属性进行具体的创建
本文的例子:ATestCompanyBuilder对象
导演类
代码语言:javascript
复制
对产品进行具体的组装。
【具体的构建类】指的是产品中的属性进行构建,
而该类是获取最终的产品对象
本文的例子:Director对象

场景

代码含义

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

代码展示
产品对象

公司对象

代码语言:javascript
复制
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<CompanyPersonnel> companyPersonnelList;
}

公司员工对象

代码语言:javascript
复制
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;
}
抽象构建类
代码语言:javascript
复制
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;
    }
}
具体的构建类
代码语言:javascript
复制
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<CompanyPersonnel> list = new ArrayList<CompanyPersonnel>();
        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;
    }

}
导演类
代码语言:javascript
复制
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();
    }
}
测试类
代码语言:javascript
复制
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);
    }
}
测试结果
代码语言:javascript
复制
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 多了,也会乱),难以维护,就可以使用该模式

附:目录结构

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

- END -

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-01-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 JAVA知识总结与分享 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 建造模式
    • 介绍
      • 意图
      • 主要解决
      • 何时使用
      • 如何解决
      • 优点
      • 缺点:
      • 使用场景
      • 注意事项
    • 代码
      • 模式角色和职责
      • 场景
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档