【HeadFirst 设计模式学习笔记】16 建筑者(Builder)模式拾零

简介:

1.概述

这个模式在Head First中没有介绍,大概是因为这个模式和工厂模式有点像。其目的主要是通过创建简单的对象构建一个复杂的对象。

2.举例

举一个例子:创建汽车的相关指标说明。

首先我们创建一个汽车的类:

  1: public class Car {
  2:  private boolean powerSteering = false;
  3:  private boolean powerWindow = false;
  4:  private String price = "";
  5:  public boolean isPowerSteargin() {
  6:  return powerSteering;
  7:  }
  8:  public void setPowerSteargin(boolean aPowerSteering) {
  9:  this.powerSteering = aPowerSteering;
 10:  }
 11:  public boolean isPowerWindow() {
 12:  return powerWindow;
 13:  }
 14:  public void setPowerWindow(boolean aPowerWindow) {
 15:  this.powerWindow = aPowerWindow;
 16:  }
 17:  public String getPrice() {
 18:  return price;
 19:  }
 20:  public void setPrice(String aPrice) {
 21:  this.price = aPrice;
 22:  }
 23:  //print the output
 24:  public String toString(){
 25:  String output = "";
 26:  output += "Power Steering : "+powerSteering+"/n";
 27:  output += "Power Window : "+powerWindow+"/n";
 28:  output += "Price : Rs "+price+"/n";
 29:  return output;
 30:  }
 31: }
 32: 

在上边的这个例子中,关于一个汽车的指标说明有三项:Power Steering、Power Window和Price。

然后我们创建一个创建汽车的类CarBuilder :

  1: abstract class CarBuilder {
  2:  protected Car car;
  3:  
  4:  public Car getCar() {
  5:  return car;
  6:  }
  7:  
  8:  public void createNewCar() {
  9:  car = new Car();
 10:  }
 11:  public abstract void setPowerSteering();
 12:  public abstract void setPowerWindow();
 13:  public abstract void setPrice();
 14: }
 15: 

现在我们创建两个具体汽车类型的创建者:Alto_LX 和 Alto_LXI

  1: public class Alto_LX extends CarBuilder{
  2:  
  3:  @Override
  4:  public void setPowerSteering() {
  5:  // TODO Auto-generated method stub
  6:  car.setPowerSteargin(false);
  7:  }
  8:  
  9:  @Override
 10:  public void setPowerWindow() {
 11:  // TODO Auto-generated method stub
 12:  car.setPowerWindow(false);
 13:  }
 14:  
 15:  @Override
 16:  public void setPrice() {
 17:  // TODO Auto-generated method stub
 18:  car.setPrice("225000");
 19:  }
 20:  
 21: }
 22: 
  1: public class Alto_LXI extends CarBuilder{
  2:  
  3:  @Override
  4:  public void setPowerSteering() {
  5:  // TODO Auto-generated method stub
  6:  car.setPowerSteargin(true);
  7:  }
  8:  
  9:  @Override
 10:  public void setPowerWindow() {
 11:  // TODO Auto-generated method stub
 12:  car.setPowerWindow(true);
 13:  }
 14:  
 15:  @Override
 16:  public void setPrice() {
 17:  // TODO Auto-generated method stub
 18:  car.setPrice("285000");
 19:  }
 20: }
 21: 

最后我们再写一个创建说明并生产汽车的类,这个类组合了具体生产汽车的类,所以该类的一个作用就是生产一部汽车(因为组合而得到的能力),另一个作用是为这个汽车创建相关指标说明(这也是因为组合得到的能力,同时也是进行了封装后提供的接口):

  1: public class Specifications {
  2:  private CarBuilder carBuilder;
  3:  public void setCarBuilder(CarBuilder aCarBuilder){
  4:  carBuilder = aCarBuilder;
  5:  }
  6:  public Car getCar(){
  7:  return carBuilder.getCar();
  8:  }
  9:  
 10:  public void constructSpecifications(){
 11:  carBuilder.createNewCar();
 12:  carBuilder.setPowerSteering();
 13:  carBuilder.setPowerWindow();
 14:  carBuilder.setPrice();
 15:  }
 16: }
 17: 

现在我们就可以造两辆带有指标说明的车了:

  1: public class AltoCarBuilderExample {
  2:  public static void main(String[] args) {
  3:  Specifications spec = new Specifications();
  4:  CarBuilder alto_lx = new Alto_LX();
  5:  CarBuilder alto_lxi = new Alto_LXI();
  6:  
  7:  //getting spec for alto lx
  8:  spec.setCarBuilder(alto_lx);
  9:  spec.constructSpecifications();
 10:  Car alto_lx_car = spec.getCar();
 11:  System.out.println("Specifiction for Alto LX");
 12:  System.out.println(alto_lx_car.toString());
 13:  
 14:  //getting spec for alto lxi
 15:  spec.setCarBuilder(alto_lxi);
 16:  spec.constructSpecifications();
 17:  Car alto_lxi_car = spec.getCar();
 18:  System.out.println("Specifiction for Alto LXI");
 19:  System.out.println(alto_lxi_car.toString());
 20:  }
 21:  
 22: }
 23: 

我们可以看到,首先我们实例化了一个创建说明的类,并且实例化了两个生产汽车的类。随后利用创建汽车能力的创建说明类来完成说明和汽车的构造。

抽象一下,UML图为:

Builder_pattern

本例中的Specification就是该图中Director。

3.与工厂方法(或抽象工厂方法)比较

该方法强调利用封装一步步完成一个复杂对象的构建,比如本例中的Specifications就是通过创建汽车、创建三项说明来完成汽车的最终构建的。而抽象工厂方法强调构建一系列产品对象,不管其复杂与否。另外,工厂方法还会根据传入的参数进行对象构建,这个建筑者模式中并没有。

Effective Java, 2nd Edition中提到:The builder pattern is a good choice when designing classes whose constructors or static factories would have more than a handful of parameters.

我们经常见过这样设计的类:

  1: Pizza(int size) { ... }        
  2: Pizza(int size, boolean cheese) { ... }    
  3: Pizza(int size, boolean cheese, boolean pepperoni) { ... }    
  4: Pizza(int size, boolean cheese, boolean pepperoni, boolean bacon) { ... }
  5: 

你可以做如下改进:

  1: Pizza pizza = new Pizza(12);
  2: pizza.setCheese(true);
  3: pizza.setPepperoni(true);
  4: pizza.setBacon(true);

这样做也有问题:通过若干步创建的pizza可能会导致对象创建的不完整,并且对于线程安全还需要多多考量。

此时我们可以使用构建者模式(此处使用嵌套类,其实和组合是一个效果):

  1: public class Pizza {
  2:   private int size;
  3:   private boolean cheese;
  4:   private boolean pepperoni;
  5:   private boolean bacon; 
  6: 
  7:   public static class Builder {
  8:     //required
  9:     private final int size; 
 10: 
 11:     //optional
 12:     private boolean cheese = false;
 13:     private boolean pepperoni = false;
 14:     private boolean bacon = false; 
 15: 
 16:     public Builder(int size) {
 17:       this.size = size;
 18:     } 
 19: 
 20:     public Builder cheese(boolean value) {
 21:       cheese = value;
 22:       return this;
 23:     } 
 24: 
 25:     public Builder pepperoni(boolean value) {
 26:       pepperoni = value;
 27:       return this;
 28:     } 
 29: 
 30:     public Builder bacon(boolean value) {
 31:       bacon = value;
 32:       return this;
 33:     } 
 34: 
 35:     public Pizza build() {
 36:       return new Pizza(this);
 37:     }
 38:   } 
 39: 
 40:   private Pizza(Builder builder) {
 41:     size = builder.size;
 42:     cheese = builder.cheese;
 43:     pepperoni = builder.pepperoni;
 44:     bacon = builder.bacon;
 45:   }
 46: }
 47: 

现在我们创建一个Pizza就是如下的方式:

  1: Pizza pizza = new Pizza.Builder(12).cheese(true).pepperoni(true).bacon(true).build();

这个例子可以与工厂模式里面的例子对比一下,就知道这两个模式的区别了。

Java中的DocumentBuilderFactory , StringBuffer, StringBuilder 都是这个模式的例子。

在线视频:http://v.youku.com/v_show/id_XMjU2OTQ5Mzg4.html




本文转自gnuhpc博客园博客,原文链接http://www.cnblogs.com/gnuhpc/archive/2012/12/21/2827640.html,如需转载请自行联系原作者

相关文章
|
11月前
|
设计模式 Java 数据库连接
【设计模式】【创建型模式】工厂方法模式(Factory Methods)
一、入门 什么是工厂方法模式? 工厂方法模式(Factory Method Pattern)是一种创建型设计模式,它定义了一个用于创建对象的接口,但由子类决定实例化哪个类。工厂方法模式使类的实例化延迟
315 16
|
11月前
|
设计模式 Java Apache
【设计模式】【创建型模式】建造者模式(Builder)
一、入门 什么是建造者模式? 建造者模式(Builder Pattern)是一种创建型设计模式,用于逐步构建复杂对象。 它通过将对象的构建过程与表示分离,使得相同的构建过程可以创建不同的表示。 为什么
648 14
|
11月前
|
设计模式 负载均衡 监控
并发设计模式实战系列(2):领导者/追随者模式
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发设计模式实战系列,第二章领导者/追随者(Leader/Followers)模式,废话不多说直接开始~
318 0
|
11月前
|
设计模式 监控 Java
并发设计模式实战系列(1):半同步/半异步模式
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发设计模式实战系列,第一章半同步/半异步(Half-Sync/Half-Async)模式,废话不多说直接开始~
436 0
|
11月前
|
设计模式 安全 Java
并发设计模式实战系列(12):不变模式(Immutable Object)
🌟 大家好,我是摘星!🌟今天为大家带来的是并发设计模式实战系列,第十二章,废话不多说直接开始~
268 0
|
11月前
|
设计模式 算法 Java
设计模式觉醒系列(04)策略模式|简单工厂模式的升级版
本文介绍了简单工厂模式与策略模式的概念及其融合实践。简单工厂模式用于对象创建,通过隐藏实现细节简化代码;策略模式关注行为封装与切换,支持动态替换算法,增强灵活性。两者结合形成“策略工厂”,既简化对象创建又保持低耦合。文章通过支付案例演示了模式的应用,并强调实际开发中应根据需求选择合适的设计模式,避免生搬硬套。最后推荐了JVM调优、并发编程等技术专题,助力开发者提升技能。
|
11月前
|
设计模式 Prometheus 监控
并发设计模式实战系列(20):扇出/扇入模式(Fan-Out/Fan-In)(完结篇)
🌟 大家好,我是摘星!🌟今天为大家带来的是并发设计模式实战系列,第二十章,废话不多说直接开始~
360 0
|
设计模式 Java 关系型数据库
设计模式:工厂方法模式(Factory Method)
工厂方法模式是一种创建型设计模式,通过将对象的创建延迟到子类实现解耦。其核心是抽象工厂声明工厂方法返回抽象产品,具体工厂重写该方法返回具体产品实例。适用于动态扩展产品类型、复杂创建逻辑和框架设计等场景,如日志记录器、数据库连接池等。优点包括符合开闭原则、解耦客户端与具体产品;缺点是可能增加类数量和复杂度。典型应用如Java集合框架、Spring BeanFactory等。
|
设计模式 前端开发 搜索推荐
前端必须掌握的设计模式——模板模式
模板模式(Template Pattern)是一种行为型设计模式,父类定义固定流程和步骤顺序,子类通过继承并重写特定方法实现具体步骤。适用于具有固定结构或流程的场景,如组装汽车、包装礼物等。举例来说,公司年会节目征集时,蜘蛛侠定义了歌曲的四个步骤:前奏、主歌、副歌、结尾。金刚狼和绿巨人根据此模板设计各自的表演内容。通过抽象类定义通用逻辑,子类实现个性化行为,从而减少重复代码。模板模式还支持钩子方法,允许跳过某些步骤,增加灵活性。
892 11
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式

热门文章

最新文章