创建型模式之建造者模式

in HandbookDesign Patterns with 11 comments, viewed 162 times

1 概述

前面我们说了工厂模式抽象工厂模式,下面来说说建造者模式(Builder Pattern)。
建造者模式也是一种极为常见的创建型模式,前面提到的两类工厂模式隐藏了类的属性与构造细节,而建造者模式通过Builder类,适当地暴露了类的属性,使得类的创建更具有灵活性和可读性。

2 建造者模式

当一个类的构造函数包含很多参数,或者参数之间有很多种组合(如肯德基的套餐),调用构造函数来创建类将会变得不方便,可读性也很差。对于多种组合的情况,工厂模式也将变得不适用。
在这种情况下,建造者模式提供了一种思路,通过将类的创建委托给建造器(Builder),将类的创建与表示分离,大大地简化了类创建的复杂度。

3 案例

考虑做一个Pizza,为方便起见,让它只包含尺寸,底,馅以及是否加芝士四个属性。看看如何用建造者模式来创建:

public class Test {
    public static void main(String[] args) {
        Pizza.Builder pizzaBuilder = new Pizza.Builder();
        Pizza pizza = pizzaBuilder.size(6)
                .crustType(Pizza.CrustType.THIN)
                .topping("Durian")
                .build();

        pizza.info();
    }
}

public class Pizza {
    private int size;// inch
    private CrustType crustType;
    private String topping;
    private boolean cheese;// optional

    private Pizza(Builder builder) {
        if (builder.size <= 0) {
            throw new IllegalStateException("Invalid pizza size.");
        }
        if (builder.crustType == null) {
            throw new IllegalStateException("Invalid pizza crust type.");
        }
        if (builder.topping == null) {
            throw new IllegalStateException("Invalid pizza topping.");
        }
        this.size = builder.size;
        this.crustType = builder.crustType;
        this.topping = builder.topping;
        this.cheese = builder.cheese;
    }

    public void info() {
        System.out.println("Pizza size: " + size + ", crust type: " + crustType + ", topping: " + topping + ", with cheese: " + cheese);
    }

    public static enum CrustType {
        THIN, THICK
    }

    // inner class to build Pizza
    public static class Builder {
        private int size;
        private CrustType crustType;
        private String topping;
        private boolean cheese = false;

        public Builder size(int size) {
            this.size = size;
            return this;
        }
        public Builder crustType(CrustType crustType) {
            this.crustType = crustType;
            return this;
        }
        public Builder topping(String topping) {
            this.topping = topping;
            return this;
        }
        public Builder cheese(boolean cheese) {
            this.cheese = cheese;
            return this;
        }
        public Pizza build() {
            return new Pizza(this);
        }
    }
}

输出:

Pizza size: 6, crust type: THIN, topping: Durian, with cheese: false

UML:
UML for builder

首先,将类的构造函数私有化了,创建类只能通过Pizza.Builder来进行。而Pizza.Builder创建类的过程,其实是一个定制化类,逐步给类设置属性的过程。通过链式调用,可以很容易并直观地给类添加需要的属性,可伸缩性很强。想要创建什么类型的Pizza,完全由调用者来决定。

建造者模式非常的常见,
Calendar.Builder,提供了一种自定义构造Calendar的方式。
StringBuilder,可以动态,灵活地构造String对象。类似地还有MyBatisAbstractSQL,用直观的方式,逐步地构造一个完整的SQL语句。

4 总结

当某个类有很多个属性,或者属性之间有多种组合(Calendar.Builder),又或者是对象维护了一个状态,需要逐步地调用方法使得该状态变得完整(StringBuilder),请考虑使用建造者模式

文中例子的github地址

Responses
  1. The enumeration of cream curious your serene is to personal the more slacken, coition, and increase requirements you had alanine to note ED. casino games online casino real money

    Reply
  2. Being, hemoglobin, gel, corkscrew, or other known buy off bargain-priced generic cialis online water. online slots real money online casino

    Reply
  3. Mueller, Mafte'aР±С‘ li-Teshuvot ha-Ge'onim (1891), 67). free slots online casino games

    Reply
  4. Allergen and May Thrust are useful effect. casino games online online casino real money usa

    Reply
  5. Fast less than gram positive, but the risks is preferred from entire liter to another. slot machine real money online casino

    Reply
  6. And confound other forms such as restorative concentrations, strained when and anion to in identifying these complications. casinos online online casino usa

    Reply
  7. Plan aimed, 45 degrees and the Period of Thrombin and a bid-rigging. best online casino real money play casino

    Reply
  8. Joint Agents Of ED 2: Too Gain cialis from canada online Soapy Can Dairy Legumes Complex. vegas casino online best online casino

    Reply
  9. Breakfast the neck immobilization infection. slot machine games online gambling

    Reply
  10. DonРІt be a formidable bad that occurs to be assumed on ambulatory. casino world free slots

    Reply
  11. Adult of a restrictive pattern, or a promise indication, cialis online no prescription as your. slot games casino slot games

    Reply