4、Builder 建造者模式

建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

建造者模式的关键特性是它将一个建造过程分解成很多步骤,也可以说,每个产品的建造会遵循同样的流程,不过流程内的每一个步骤都不尽相同。

一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。

意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。

主要解决:主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。

举例

在下面这个故事里,我们会定义一个叫作星巴克饮料机(StarbucksBuilder)的机器,用于制造星巴克饮料。StarbucksBuilder要经过很多步骤来做一杯饮料,比如buildSize() 和 buildDrink(),并且最终返回制成的饮料。

类图

代码示例

package designpatterns.builder;
 
// 待构建产品
class Starbucks {
    private String size;
    private String drink;
 
    public void setSize(String size) {
        this.size = size;
    }
 
    public void setDrink(String drink) {
        this.drink = drink;
    }
}
 
//抽象builder
abstract class StarbucksBuilder {
    protected Starbucks starbucks;
 
    public Starbucks getStarbucks() {
        return starbucks;
    }
 
    public void createStarbucks() {
        starbucks = new Starbucks();
        System.out.println("a drink is created");
    }
 
    public abstract void buildSize();
    public abstract void buildDrink();
}
 
// 泡茶builder
class TeaBuilder extends StarbucksBuilder {
    public void buildSize() {
        starbucks.setSize("large");
        System.out.println("build large size");
    }
 
    public void buildDrink() {
        starbucks.setDrink("tea");
        System.out.println("build tea");
    }
 
}
 
// 泡咖啡builder
class CoffeeBuilder extends StarbucksBuilder {
    public void buildSize() {
        starbucks.setSize("medium");
        System.out.println("build medium size");
    }
 
    public void buildDrink() {
        starbucks.setDrink("coffee");
        System.out.println("build coffee");
    }
}
 
//指导如何封装builder
class Waiter {
    private StarbucksBuilder starbucksBuilder;
 
    public void setStarbucksBuilder(StarbucksBuilder builder) {
        starbucksBuilder = builder;
    }
 
    public Starbucks getstarbucksDrink() {
        return starbucksBuilder.getStarbucks();
    }
 
    public void constructStarbucks() {
        starbucksBuilder.createStarbucks();
        starbucksBuilder.buildDrink();
        starbucksBuilder.buildSize();
    }
}
 
//客户
public class Customer {
    public static void main(String[] args) {
        Waiter waiter = new Waiter();
        StarbucksBuilder coffeeBuilder = new CoffeeBuilder();
 
        //也可以用泡茶builder沏茶
        //StarbucksBuilder teaBuilder = new TeaBuilder();
 
        waiter.setStarbucksBuilder(coffeeBuilder);
        waiter.constructStarbucks();
 
        //取到饮料
        Starbucks drink = waiter.getstarbucksDrink();
 
    }
}

应用

StringBuilder类库就使用了建造者模式:

StringBuilder strBuilder= new StringBuilder();

strBuilder.append("one");

strBuilder.append("two");

strBuilder.append("three");

String str= strBuilder.toString();

append()方法类似于星巴克例子中的一个步骤,toString()方法是其中的最后一步。

建造者模式优点

首先,建造者模式的封装性很好。使用建造者模式可以有效的封装变化,在使用建造者模式的场景中,一般产品类和建造者类是比较稳定的,因此,将主要的业务逻辑封装在导演类中对整体而言可以取得比较好的稳定性。

其次,建造者模式很容易进行扩展。如果有新的需求,通过实现一个新的建造者类就可以完成,基本上不用修改之前已经测试通过的代码,因此也就不会对原有功能引入风险。

建造者模式和工厂模式的区别

我们可以看到,建造者模式与工厂模式是极为相似的,总体上,建造者模式仅仅只比工厂模式多了一个导演类”的角色。在建造者模式的类图中,假如把这个导演类看做是最终调用的客户端,那么图中剩余的部分就可以看作是一个简单的工厂模式了。

 与工厂模式相比,建造者模式一般用来创建更为复杂的对象,因为对象的创建过程更为复杂,因此将对象的创建过程独立出来组成一个新的类——导演类。也就是说,工厂模式是将对象的全部创建过程封装在工厂类中,由工厂类向客户端提供最终的产品;而建造者模式中,建造者类一般只提供产品类中各个组件的建造,而将具体建造过程交付给导演类。由导演类负责将各个组件按照特定的规则组建为产品,然后将组建好的产品交付给客户端。

猜你喜欢

转载自blog.csdn.net/sinat_37138973/article/details/88242740