Builder模式也叫建造者模式或者生成器模式,是由GoF提出的23种设计模式中的一种。Builder模式是一种对象创建型模式之一,用来隐藏复合对象的创建过程,它把复合对象的创建过程加以抽象,通过子类继承和重载的方式,动态地创建具有复合属性的对象。

  建造者模式的结构

  角色

  在这样的设计模式中,有以下几个角色:

    1 builder:为创建一个产品对象的各个部件指定抽象接口。

    2 ConcreteBuilder:实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,并提供一个检索产品的接口。

    3 Director:构造一个使用Builder接口的对象。

    4 Product:表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,包括将这些部件装配成最终产品的接口。

  首先,举个例子,建造者模式我们比方我们要造个房子。

  房子的图纸

 public class House {
//地板
private String floor;
//墙
private String wall;
//房顶
private String roof; public String getFloor() {
return floor;
}
public void setFloor(String floor) {
this.floor = floor;
}
public String getWall() {
return wall;
}
public void setWall(String wall) {
this.wall = wall;
}
public String getRoof() {
return roof;
}
public void setRoof(String roof) {
this.roof = roof;
}
}

  有了图纸后,最笨的方法就是自己造房子

  客户端

 public class MainClass {
public static void main(String[] args) {
//客户直接造房子
House house = new House(); house.setFloor("地板");
house.setWall("墙");
house.setRoof("屋顶"); System.out.println(house.getFloor());
System.out.println(house.getWall());
System.out.println(house.getRoof());
}
}

  可是这样的方法不是很好,真正我们造房子都是找施工队,所以我们要把造房子分离出来,交给施工队

  新建一个施工队,为了扩展性,声明一个施工队的接口

 public interface HouseBuilder {
//修地板
public void makeFloor();
//修墙
public void makeWall();
//修屋顶
public void makeRoof();
//获得修好的房子
public House getHouse();
}

  新建一个施工队,实现此接口

 public class LoufangBuilder implements HouseBuilder{
House house = new House(); @Override
public void makeFloor() {
house.setFloor("楼房->地板");
} @Override
public void makeWall() {
house.setWall("楼房->墙");
} @Override
public void makeRoof() {
house.setRoof("楼房->屋顶");
} @Override
public House getHouse() {
return house;
}
}

  客户端

 public class MainClass {
public static void main(String[] args) {
//施工队造房子
HouseBuilder loufangBuilder = new LoufangBuilder();
loufangBuilder.makeFloor();
loufangBuilder.makeWall();
loufangBuilder.makeRoof(); House house = loufangBuilder.getHouse();
System.out.println(house.getFloor());
System.out.println(house.getWall());
System.out.println(house.getRoof());
}
}

  可以看到,这样子造房子就交给施工队了,但可以看到造房子的具体细节还在客户端里,如图。

  

  这就相当于我们在指导施工队干活,这肯定不是最好的方案,最好的解决方案,是由一个设计师也可以说是指挥者来指导工程队,所以在新建一个指挥者

 public class HouseDirector {
private HouseBuilder houseBuilder; public HouseDirector(HouseBuilder houseBuilder){
this.houseBuilder = houseBuilder;
} public void make(){
houseBuilder.makeFloor();
houseBuilder.makeWall();
houseBuilder.makeRoof();
}
}

  客户端

 public class MainClass {
public static void main(String[] args) {
//施工队造房子
HouseBuilder loufangBuilder = new LoufangBuilder();
// loufangBuilder.makeFloor();
// loufangBuilder.makeWall();
// loufangBuilder.makeRoof();
HouseDirector houseDirector = new HouseDirector(loufangBuilder);
houseDirector.make(); House house = loufangBuilder.getHouse();
System.out.println(house.getFloor());
System.out.println(house.getWall());
System.out.println(house.getRoof());
}
}

  这样子,把施工队交给这个设计者,施工细节的工作就由这个设计者执行了。

  当然,还有一种写法,有一些细微的改动,也是更常用的,就是设计者(Director)不在构造时传入builder,而是在调用方法时,才传入,像这样

 public class HouseDirector {
public void make(HouseBuilder houseBuilder){
houseBuilder.makeFloor();
houseBuilder.makeWall();
houseBuilder.makeRoof();
}
}

  客户端

 public class MainClass {
public static void main(String[] args) {
//施工队造房子
HouseBuilder loufangBuilder = new LoufangBuilder(); HouseDirector houseDirector = new HouseDirector();
houseDirector.make(loufangBuilder); House house = loufangBuilder.getHouse();
System.out.println(house.getFloor());
System.out.println(house.getWall());
System.out.println(house.getRoof());
}
}

  这样子,出来的效果是一样的。

  这就是一个简单的建造者模式

  这样也提高了系统的扩展性与可维护性,如果不想造楼房了,想造一个别墅,只需新增一个别墅施工队就好了,像这样

 public class BieshuBuilder implements HouseBuilder{
House house = new House(); @Override
public void makeFloor() {
house.setFloor("别墅->地板");
} @Override
public void makeWall() {
house.setWall("别墅->墙");
} @Override
public void makeRoof() {
house.setRoof("别墅->屋顶");
} @Override
public House getHouse() {
return house;
}
}

  客户端只需把施工队换成别墅施工队

public class MainClass {
public static void main(String[] args) {
//施工队造房子
HouseBuilder bieshuBuilder = new BieshuBuilder();//只需要修改这里 HouseDirector houseDirector = new HouseDirector();
houseDirector.make(bieshuBuilder); House house = bieshuBuilder.getHouse();
System.out.println(house.getFloor());
System.out.println(house.getWall());
System.out.println(house.getRoof());
}
}

  适用范围

  1、对象的创建:Builder模式是为对象的创建而设计的模式

  2、创建的是一个复合对象:被创建的对象为一个具有复合属性的复合对象

  3、关注对象创建的各部分的创建过程:不同的工厂(这里指builder生成器)对产品属性有不同的创建方法

java设计模式-----6、建造者模式的更多相关文章

  1. 折腾Java设计模式之建造者模式

    博文原址:折腾Java设计模式之建造者模式 建造者模式 Separate the construction of a complex object from its representation, a ...

  2. Java 设计模式之建造者模式(四)

    原文地址:Java 设计模式之建造者模式(四) 博客地址:http://www.extlight.com 一.前言 今天继续介绍 Java 设计模式中的创建型模式--建造者模式.上篇设计模式的主题为 ...

  3. java设计模式3——建造者模式

    java设计模式3--建造者模式 1.建造者模式介绍: 建造者模式属于创建型模式,他提供了一种创建对象得最佳方式 定义: 将一个复杂对象的构建和与它的表示分离,使得同样的构建过程可以创建不同的表示 主 ...

  4. Java设计模式之建造者模式(Builder)

    前言: 最近一直在学习okHttp,也对其做了一些整理,okHttp和Retrofit结合大大加速我们的开发效率,源码里面采用了很多设计模式,今天我们来学习一下其中的设计模式之一建造者模式. 建造者模 ...

  5. Java设计模式之三 ----- 建造者模式和原型模式

    前言 在上一篇中我们学习了工厂模式,介绍了简单工厂模式.工厂方法和抽象工厂模式.本篇则介绍设计模式中属于创建型模式的建造者模式和原型模式. 建造者模式 简介 建造者模式是属于创建型模式.建造者模式使用 ...

  6. Java设计模式之三建造者模式和原型模式

    建造者模式 简介 建造者模式是属于创建型模式.建造者模式使用多个简单的对象一步一步构建成一个复杂的对象.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式.简单的来说就是将一个复杂的东西 ...

  7. java设计模式之建造者模式

    学习了设计模式,一直感觉有进步又没有进步,与同学.同事探讨了一下.变化不可能一会就可以的,需要努力坚持.不管进步大小,也不管是否进步,做到勿忘初心,做自己喜欢的事情就好.还有几个设计模式一直没有写,原 ...

  8. java设计模式之四建造者模式(Builder)

    工厂类模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来进行管理,用来创建复合对象,所谓复合对象就是指某个类具有不同的属性,其实建造者模式就是前面抽象工厂模式和最后的Test结合起来得到 ...

  9. java设计模式3.建造者模式、原型模式

    建造者模式 一个产品常有不同的组成部分作为产品的零件,有些情况下,一个对象会有一些重要的性质,在它们没有恰当的值之前,对象不能作为一个完整的产品使用,有些时候,一个对象的一些性质必须按照某个顺序赋值才 ...

  10. JAVA设计模式总结—建造者模式

    建造者模式 模式动机与定义 ​ 首先建造者模式的动机是为了创建复杂对象,简化传统的创建方法,提高创建的效率和可读性. ​ 像图中的这个例子,用户的需求是驾驶一辆汽车,但是对于用户来说是不需要了解汽车装 ...

随机推荐

  1. apollo配置中心初探

    近在搞微服务框架的开发,需要有一个配置中心来满足统一管理业务应用以及组件的配置,在此期间也使用了多个配置中心比如:spring cloud config,自研的配置中心,当然还有apollo. spr ...

  2. [Objective-C语言教程]多态(26)

    多态性这个词表示有许多形式. 通常,当存在类的层次结构并且通过继承相关时,会发生多态性. Objective-C多态表示对成员函数的调用将导致执行不同的函数,具体取决于调用该函数的对象的类型. 考虑下 ...

  3. Android 线刷小白教程

    Android 线刷小白教程 再说一遍,绝不使用刷机精灵等软件. 一.概念 安卓系统一般把rom芯片分成7个区,如果再加上内置sd卡这个分区,就是8个: hboot分区----------负责启动. ...

  4. 爬虫实战2:爬头条网美图--Ajax图片加载处理

    完整代码经测试可成功运行,目的是抓取头条网输入街拍后的图片,涉及的知识点如下 1. md5加密使用方法 方法1:不创建实例对象,直接使用 >>> from hashlib impor ...

  5. SpringData JPA复合主键

    上一篇博客简单介绍了SpringData JPA实现简单的CRUD,分页与多条件的排序,那里的主键类型是Long,有时我们会遇到主键不是一个的,复合主键,经过调研如下.确定一个人,不能只根据他的姓名来 ...

  6. Spring注解大全,汇总版

    Spring使用的注解大全和解释 注解 解释 @Controller 组合注解(组合了@Component注解),应用在MVC层(控制层),DispatcherServlet会自动扫描注解了此注解的类 ...

  7. JavaScript DOM编程艺术 笔记(三)函数

    函数function 是在你的代码里随时调用的语句 每个函数是个短小的脚本,arguments,传递的参数 function name(arguments){ statements; } functi ...

  8. postman小结

    1.get和post请求,get有限制2k,post没有限制post安全 在选择的时候别把get post选错然后,run 2.data 选成txt文件  utf-8 ip ip,result12.1 ...

  9. Vue项目开发目录结构

    最近做一些CI+Vue开发的简单项目,由于刚开始一直从事后端,对Vue了解不是很多,fork了团队的项目代码发现项目的文件夹很多,一时间有些懵,上网上参考了部分资料,博客园中的放晴的天空与狮子爱吃草两 ...

  10. JVectorMap地图插件.Net版开源

    jVectorMap地图插件只要浏览器技术JavaScript.CSS,HTML,SVG或VML就可以浏览使用,不需要Flash或其他专有的浏览 器插件.所以jVectorMap在所有现代移动浏览器上 ...