构造者模式——Builder

构造者模式——Builder

  本文是《Java设计模式》Chapter15 Builder的总结。

 

一、Builder模式实践
构造者模式——Builder_第1张图片

  在本例中,用诸如以下的字符串构造Reservation对象,字符串可能不合法或者缺少某些属性。

  为了保证构造出来的Reservation对象是合法对象,引入中间对象ReservationBuilder,临时存储已经读取的属性;最终用它的方法build()来返回合法对象或者抛出异常。“将字符串逐步转化到中间对象中的工作”交给ReservationParser来做吧^_^

 

  下面展示了如何使用Builder来逐步构造合法对象

public class ShowForgiving {
    public static void main(String[] args) {
        //待转化字符串
        String sample = "Date, November 5, Headcount, 250, "
                + "City, Springfield, DollarsPerHead, 9.95, HasSite, False";
        //中间对象builder
        ReservationBuilder builder = new ForgivingBuilder();
        try {
            //转换器内部包裹中间对象;然后开始逐步构造中间对象
            new ReservationParser(builder).parse(sample);
            //尝试返回有效对象Reservation(不同builder对有效性有“容忍度”)
            Reservation res = builder.build();
            System.out.println("Forgiving builder: " + res);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

 

 其实下面代码是不重要的,这里只是为了看一下细节:

public class ReservationParser {
    private ReservationBuilder builder;

    public ReservationParser(ReservationBuilder builder) {
        this.builder = builder;
    }

    public void parse(String s) throws ParseException {
        String[] tokens = s.split(",\\s*");
        for (int i = 0; i < tokens.length; i += 2) {
            String type = tokens[i];
            String val = tokens[i + 1];

            if ("date".compareToIgnoreCase(type) == 0) {
                Calendar now = Calendar.getInstance();
                DateFormat formatter = DateFormat.getDateInstance();
                Date d = formatter.parse(val + ", " + now.get(Calendar.YEAR));
                builder.setDate(ReservationBuilder.futurize(d));
            }
            else if ("headcount".compareToIgnoreCase(type) == 0) 
                builder.setHeadcount(Integer.parseInt(val));
            else if ("City".compareToIgnoreCase(type) == 0)
                builder.setCity(val.trim());
            else if ("DollarsPerHead".compareToIgnoreCase(type) == 0) 
                builder.setDollarsPerHead(new Dollars(Double.parseDouble(val)));
            else if ("HasSite".compareToIgnoreCase(type) == 0)
                builder.setHasSite(val.equalsIgnoreCase("true"));
        }
    }
}
 

 

二、Builder模式好处(P165 Summary)

       The Builder pattern separate the construction of a  complex object from its representation. This has the immediate effect of making a complex target class simpler. It lets a builder class("ReservationBuilder") focus on the proper construction of an object, leaving the target class("Reservation") to focus on the operation of valid instance. This is especially useful when you want to ensure the validity of an object before instantiating it and don't want the associated logic to appear in the target class's constructors. A builder also accommodates step-by-step construction, which often occurs when you create an object by parsing text .

 

       简言之,Builder 模式将对象的构造过程分离出来(就好像把Ctor做成一个类似的)!通常是因为构造过程比较复杂,如:

       构造是需要考虑产生对象的有效性;需要通过解析字符串来逐步构建对象。

你可能感兴趣的:(设计模式(抽象&封装))