【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,如需转载请自行联系原作者

相关文章
|
1月前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
|
1月前
|
设计模式 开发者 Python
Python编程中的设计模式:工厂方法模式###
本文深入浅出地探讨了Python编程中的一种重要设计模式——工厂方法模式。通过具体案例和代码示例,我们将了解工厂方法模式的定义、应用场景、实现步骤以及其优势与潜在缺点。无论你是Python新手还是有经验的开发者,都能从本文中获得关于如何在实际项目中有效应用工厂方法模式的启发。 ###
|
1月前
|
设计模式 安全 Java
Kotlin - 改良设计模式 - 构建者模式
Kotlin - 改良设计模式 - 构建者模式
|
1月前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
45 1
|
2月前
|
设计模式 Java Kotlin
Kotlin学习笔记 - 改良设计模式 - 迭代器模式
Kotlin学习笔记 - 改良设计模式 - 迭代器模式
36 2
|
2月前
|
设计模式 JavaScript Scala
Kotlin学习笔记 - 改良设计模式 - 责任链模式
Kotlin学习笔记 - 改良设计模式 - 责任链模式
47 0
|
2月前
|
设计模式 Java Kotlin
Kotlin 学习笔记- 改良设计模式 - 装饰者模式
Kotlin 学习笔记- 改良设计模式 - 装饰者模式
34 0
|
3月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。
|
2月前
|
设计模式 Java Kotlin
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
本教程详细讲解Kotlin语法,适合希望深入了解Kotlin的开发者。对于快速学习Kotlin语法,推荐查看“简洁”系列教程。本文重点介绍了构建者模式在Kotlin中的应用与改良,包括如何使用具名可选参数简化复杂对象的创建过程,以及如何在初始化代码块中对参数进行约束和校验。
33 3
|
3月前
|
设计模式 算法 安全
设计模式——模板模式
模板方法模式、钩子方法、Spring源码AbstractApplicationContext类用到的模板方法
设计模式——模板模式