建造者模式
外观

建造者模式(英:Builder Pattern),也译为生成器模式,是一种对象构建設計模式[1]。它可以將複雜對象的建造過程抽象出來(抽象類別),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象。
适用性
[编辑]在以下情况使用建造者模式:
- 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时;
- 当构造过程必须允许被构造的对象有不同的表示时。
参与者
[编辑]
- Builder
- 为创建一个Product对象的各个部件指定抽象接口。
- ConcreteBuilder
- 实现Builder的接口以构造和装配该产品的各个部件。
- 定义并明确它所创建的表示。
- 提供一个检索产品的接口
- Director
- 构造一个使用Builder接口的对象。
- Product
- 表示被构造的复杂对象。ConcreateBuilder创建该产品的内部表示并定义它的装配过程。
- 包含定义组成部件的类,包括将这些部件装配成最终产品的接口。
协作
[编辑]客户创建Director对象,并用它所想要的Builder对象进行配置。
- 一旦产品部件被生成,指导者就会通知建造者。
- 建造者处理指导者的请求,并将部件添加到该产品中。
- 客户从建造者中检索产品。
範例
[编辑]Java
[编辑]Java例子:
/** "Product" */
class Pizza {
private String dough = "";
private String sauce = "";
private String topping = "";
public void setDough (String dough) { this.dough = dough; }
public void setSauce (String sauce) { this.sauce = sauce; }
public void setTopping (String topping) { this.topping = topping; }
}
/** "Abstract Builder" */
abstract class PizzaBuilder {
protected Pizza pizza;
public Pizza getPizza() { return pizza; }
public void createNewPizzaProduct() { pizza = new Pizza(); }
public abstract void buildDough();
public abstract void buildSauce();
public abstract void buildTopping();
}
/** "ConcreteBuilder" */
class HawaiianPizzaBuilder extends PizzaBuilder {
public void buildDough() { pizza.setDough("cross"); }
public void buildSauce() { pizza.setSauce("mild"); }
public void buildTopping() { pizza.setTopping("ham+pineapple"); }
}
/** "ConcreteBuilder" */
class SpicyPizzaBuilder extends PizzaBuilder {
public void buildDough() { pizza.setDough("pan baked"); }
public void buildSauce() { pizza.setSauce("hot"); }
public void buildTopping() { pizza.setTopping("pepperoni+salami"); }
}
/** "Director" */
class Waiter {
private PizzaBuilder pizzaBuilder;
public void setPizzaBuilder (PizzaBuilder pb) { pizzaBuilder = pb; }
public Pizza getPizza() { return pizzaBuilder.getPizza(); }
public void constructPizza() {
pizzaBuilder.createNewPizzaProduct();
pizzaBuilder.buildDough();
pizzaBuilder.buildSauce();
pizzaBuilder.buildTopping();
}
}
/** A customer ordering a pizza. */
class BuilderExample {
public static void main(String[] args) {
Waiter waiter = new Waiter();
PizzaBuilder hawaiianPizzabuilder = new HawaiianPizzaBuilder();
PizzaBuilder spicyPizzabuilder = new SpicyPizzaBuilder();
waiter.setPizzaBuilder ( hawaiianPizzabuilder );
waiter.constructPizza();
Pizza pizza = waiter.getPizza();
}
}
C#
[编辑]C#例子:
// Represents a product created by the builder.
public class Bicycle
{
public Bicycle(string maker, string model, string colour, int height)
{
Maker = maker;
Model = model;
Colour = colour;
Height = height;
}
public string Maker { get; set; }
public string Model { get; set; }
public int Height { get; set; }
public string Colour { get; set; }
}
// The builder abstraction.
public interface IBicycleBuilder
{
Bicycle GetResult();
string Colour { get; set; }
int Height { get; set; }
}
// Concrete builder implementation.
public class GTBicyclesBuilder : IBicycleBuilder
{
public Bicycle GetResult()
{
return Height == 29 ? new Bicycle("GT Bicycles Inc.", "Avalanche", Colour, Height) : null;
}
public string Colour { get; set; }
public int Height { get; set; }
}
// The director.
public class MountainBikeBuildDirector
{
private IBicycleBuilder _builder;
public MountainBikeBuildDirector(IBicycleBuilder builder)
{
_builder = builder;
}
public void Construct()
{
_builder.Colour = "Red";
_builder.Height = 29;
}
public Bicycle GetResult()
{
return this._builder.GetResult();
}
}
public class Client
{
public void DoSomethingWithBicycles()
{
var director = new MountainBikeBuildDirector(new GTBicyclesBuilder());
// Director controls the stepwise creation of product and returns the result.
director.Construct();
Bicycle myMountainBike = director.GetResult();
}
}
PHP
[编辑]PHP例子:
<?php
//設計模式:生成器模式
//Coder: rollenc ( http://www.rollenc.com )
interface Builder {
function buildPartA(); //创建部件A比如创建汽车车轮
//创建部件B 比如创建汽车方向盘
function buildPartB();
//创建部件C 比如创建汽车发动机
function buildPartC();
//返回最后组装成品结果 (返回最后装配好的汽车)
//成品的组装过程不在这里进行,而是转移到下面的Director类中进行.
//从而实现了解耦过程和部件
//return Product
function getResult();
}
class Director {
private $builder;
public function __construct($builder ) {
$this->builder = $builder;
}
// 将部件partA partB partC最后组成复杂对象
//这里是将车轮、方向盘和发动机组装成汽车的过程
public function construct() {
$this->builder->buildPartA();
$this->builder->buildPartB();
$this->builder->buildPartC();
}
}
class ConcreteBuilder implements Builder {
public $partA, $partB, $partC;
public function buildPartA() {
echo 'partA is builded' . "\n";
}
public function buildPartB() {
echo 'partB is builded' . "\n";
}
public function buildPartC() {
echo 'partC is builded' . "\n";
}
public function getResult () {
echo 'Return product.' . "\n";
return 1;
}
}
$builder = new ConcreteBuilder();
$director = new Director( $builder );
$director->construct();
$product = $builder->getResult();
?>
注意问题
[编辑]- 装配和构造接口
- 建造者逐步的构造它们的产品。因此建造者介面必须足够普遍,以便为各种类型的具体建造者构造产品。
- 没有抽象类
- 通常情况下,由具体建造者生成的产品,它们的表示相差是如此之大以至于给不同的产品以公共父类没有太大意思。
- 在建造者中預設的方法为空
- 定义为空方法可以使客户只重定义他们所感兴趣的操作。
效果
[编辑]- 它使你可以改变一个产品的内部表示
- 它将构造代码和表示代码分开
- 它使你可对构造过程进行更精细的控制
相关模式
[编辑]抽象工厂模式与建造者相似,因为它也可以创建复杂对象。主要的区别是建造者模式着重于一步步构造一个复杂对象。而抽象工厂模式着重于多个系列的产品对象(简单的或是复杂的)。建造者在最后的一步返回产品,而对于抽象工廠来说,产品是立即返回的。
组成模式通常是用建造者生成的。
引用
[编辑]- ^ Gamma et al. 1994,第97頁.
- ^ The Builder design pattern - Structure and Collaboration. w3sDesign.com. [2017-08-12].