Java设计模式------建造者模式(Builder)
设计模式两大原则:
一、找出应用中变化之处,把它们独立,不要和那些不需要变化的代码混在一起
二、面向接口编程而不是面向具体实现
一、前言
1、定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示
2、主要作用:在用户不知道对象的建造过程和细节的情况下就可以直接创建复杂的对象。
3、如何使用:用户只需要给出指定复杂对象的类型和内容,建造者模式负责按顺序创建复杂对象(把内部的建造过程和细节隐藏起来)
4、解决的问题:
(1)、方便用户创建复杂的对象(不需要知道实现过程)
(2)、代码复用性 & 封装性(将对象构建过程和细节进行封装 & 复用)
5、注意事项:与工厂模式的区别是:建造者模式更加关注与零件装配的顺序,一般用来创建更为复杂的对象
二、实现方式有三种
(1)重叠构造器
(2)通过Client、Director、Builder和Product形成的建造者模式
(3)通过静态内部类方式实现零件无序装配化构造
第一种方法
直接上代码
/**
* 用户实体
*/
public class User {
/**
* 唯一标识
*/
private int id;
/**
* 姓名
*/
private String name;
/**
* 性别
*/
private int sex;
/**
* 出生年月
*/
private Date birthDate;
/**
* 备注
*/
private String note;
public User(){
}
//方法一 、使用重叠构造器
public User(int id,String name){
this(id,name,0);
}
public User(int id,String name,int sex){
this(id,name,sex,new Date());
}
public User(int id,String name,int sex,Date birthDate){
this(id,name,sex,birthDate,"");
}
public User(int id,String name,int sex,Date birthDate,String note){
this.id = id;
this.name = name;
this.sex = sex;
this.birthDate = birthDate;
this.note = note;
}
}
① 这个构造器调用,通常需要许多你本不想设置的参数,但还是不得不为它们传递值
②当有许多参数的时候,创建使用代码会很难写,并且较难以阅读
第二种方法
一般有这几个角色:
抽象建造者(builder):描述具体建造者的公共接口,一般用来定义建造细节的方法,并不涉及具体的对象部件的创建。
具体建造者(ConcreteBuilder):描述具体建造者,并实现抽象建造者公共接口。
指挥者(Director):调用具体建造者来创建复杂对象(产品)的各个部分,并按照一定顺序(流程)来建造复杂对象。
产品(Product):描述一个由一系列部件组成较为复杂的对象。
具体步骤:
1、创建抽象建造者定义造房步骤
2、创建工人具体实现造房步骤
3、创建承包商指挥工人施工
4、验收,检查是否建造完成
代码双手奉上给各位大佬
抽象建造者
/**
* 创建抽象建造者定义 建房步骤
*/
abstract class Builder {
/**
* 1、建造地基
*/
abstract void buildFoundation();
/**
* 2、钢筋工程
*/
abstract void buildIronProject();
/**
* 3、铺设电线
*/
abstract void buildWireProject();
/**
* 4、粉刷墙体
*/
abstract void buildPaintProject();
/**
* 5、完工-获取最终产品
*/
abstract House getHouse();
}
产品
/**
* 定义最终的产品 房子
*/
public class House {
/**
* 1、建造地基
*/
private String foundation;
/**
* 2、钢筋工程
*/
private String ironProject;
/**
* 3、铺设电线
*/
private String wireProject;
/**
* 4、粉刷墙体
*/
private String paintProject;
public String getFoundation() {
return foundation;
}
public void setFoundation(String foundation) {
this.foundation = foundation;
}
public String getIronProject() {
return ironProject;
}
public void setIronProject(String ironProject) {
this.ironProject = ironProject;
}
public String getWireProject() {
return wireProject;
}
public void setWireProject(String wireProject) {
this.wireProject = wireProject;
}
public String getPaintProject() {
return paintProject;
}
public void setPaintProject(String paintProject) {
this.paintProject = paintProject;
}
@Override
public String toString() {
return super.toString();
}
}
具体建造者
/**
* 工人具体实现建房步骤
*/
public class HouseBuilder extends Builder {
private House house;
public HouseBuilder(){
this.house = new House();
}
@Override
void buildFoundation() {
house.setFoundation("地基");
System.out.println("1----开始建造地基");
}
@Override
void buildIronProject() {
house.setIronProject("钢筋工程");
System.out.println("2----开始钢筋工程");
}
@Override
void buildWireProject() {
house.setIronProject("电缆");
System.out.println("3----开始铺设电缆");
}
@Override
void buildPaintProject() {
house.setIronProject("粉刷房子");
System.out.println("4----开始粉刷房子");
}
@Override
House getHouse() {
return house;
}
}
指挥者
/**
* 承包商 指挥工人施工
*/
public class HouseDirector {
//指挥工人按顺序造房
public House create(Builder builder) {
builder.buildFoundation();
builder.buildIronProject();
builder.buildWireProject();
builder.buildPaintProject();
return builder.getHouse();
}
}
测试
public class HouseTest {
public static void main(String[] args) {
HouseDirector director = new HouseDirector();
House house = director.create(new HouseBuilder());
System.out.println(house.toString());
}
}
第三种方法
1) 主要角色有三个 抽象建造者、具体建造者、产品
2) 产品的属性可以随意组装使用更加灵活,更符合定义
3)内部可以有复杂对象的默认实现
①内部类写法
/**
* 用户实体
*/
public class User {
/**
* 唯一标识
*/
private int id;
/**
* 姓名
*/
private String name;
/**
* 性别
*/
private int sex;
/**
* 出生年月
*/
private Date birthDate;
/**
* 备注
*/
private String note;
public User(){
}
//内部类 builder 构造器模式
private User(Builder builder) {
this.id = builder.id;
this.name = builder.name;
this.sex = builder.sex;
this.birthDate = builder.birthDate;
this.note = builder.note;
}
public static class Builder {
//需要组装的部件
private int id;
private String name;
private int sex;
private Date birthDate;
private String note;
//最终组装的成品
public User build() {
return new User(this);
}
//组装的过程 以下是可任意组装自己
public Builder(){
}
public Builder setId(int id) {
this.id = id;
return this;
}
public Builder setName(String name) {
this.name = name;
return this;
}
public Builder setSex(int sex) {
this.sex = sex;
return this;
}
public Builder setBirthDate(Date birthDate) {
this.birthDate = birthDate;
return this;
}
public Builder setNote(String note) {
this.note = note;
return this;
}
}
@Override
public String toString() {
return "id="+id
+",name="+name
+",sex="+sex
+",name="+name
+",birthDate="+birthDate
+"note="+note;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public int getSex() {
return sex;
}
public Date getBirthDate() {
return birthDate;
}
public String getNote() {
return note;
}
}
② 第二种实现方式
建造者
/**
* Builder.java
* 建造者
*/
abstract class Builder {
//汉堡
abstract Builder bulidA(String mes);
//饮料
abstract Builder bulidB(String mes);
//薯条
abstract Builder bulidC(String mes);
//甜品
abstract Builder bulidD(String mes);
//获取套餐
abstract Product build();
}
产品
/**
* Product.java
* 产品(麦当劳套餐)
*/
public class Product {
private String buildA="汉堡";
private String buildB="饮料";
private String buildC="薯条";
private String buildD="甜品";
public String getBuildA() {
return buildA;
}
public void setBuildA(String buildA) {
this.buildA = buildA;
}
public String getBuildB() {
return buildB;
}
public void setBuildB(String buildB) {
this.buildB = buildB;
}
public String getBuildC() {
return buildC;
}
public void setBuildC(String buildC) {
this.buildC = buildC;
}
public String getBuildD() {
return buildD;
}
public void setBuildD(String buildD) {
this.buildD = buildD;
}
@Override
public String toString() {
return buildA+"\n"+buildB+"\n"+buildC+"\n"+buildD+"\n"+"组成套餐";
}
}
具体建造者
/**
* ConcreteBuilder.java
* 具体建造者(服务员)
*/
public class ConcreteBuilder extends Builder{
private Product product;
public ConcreteBuilder() {
product = new Product();
}
@Override
Product build() {
return product;
}
@Override
Builder bulidA(String mes) {
product.setBuildA(mes);
return this;
}
@Override
Builder bulidB(String mes) {
product.setBuildB(mes);
return this;
}
@Override
Builder bulidC(String mes) {
product.setBuildC(mes);
return this;
}
@Override
Builder bulidD(String mes) {
product.setBuildD(mes);
return this;
}
}
测试
/**
* Test.java
* 测试类
*/
public class Test {
public static void main(String[] args) {
ConcreteBuilder concreteBuilder = new ConcreteBuilder();
Product build = concreteBuilder
.bulidA("牛肉煲")
// .bulidC("全家桶")
.bulidD("冰淇淋")
.build();
System.out.println(build.toString());
}
}