实例:
导出数据时,不管导出为何种文件格式(文本文件、数据库文件、XML...),在实现时步骤基本一样:
先拼接文件头内容,再拼接文件体内容,然后是文件尾内容,最后把拼接好的内容输出成文件...
这有什么问题?
1.构建每种输出格式文件时,都要重复这几个步骤;2.今后可能会有很多不同的输出格式的要求,这就需要在处理不变的情况下,能方便的切换不同输出格式的处理
换句话说,就是构建每种格式文件的处理过程,应该和具体的步骤实现分开,这样就能复用处理过程,并且能很容易的切换不同的输出格式
定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示
类图:
-
Builder :生成器接口,定义创建一个Product对象所需的各个部件的操作。标准的Builder一般至少有两个方法,一个建造产品,一个返回产品
-
ConcreteBuilder:生成器实现,实现各个部件的创建,并负责组装Product的各个部件,同时提供方法返回组装完成的产品对象给用户
-
Director:指导者,导向者。不与产品类发生依赖关系,使用Builder接口,以一个统一的过程来构建所需的Product对象。
-
Product:产品,被生成器构建的复杂对象,包含多个部件。一般会有比较多的代码量。在本类图中,产品类是一个具体的类,而非抽象类。实际编程中,产品类可以是由一个抽象类与它的不同实现组成,也可以是由多个抽象类与他们的实现组成
/** *指导类 */ class Director { private Builder builder; public Director(Builder builder){ this.builder=builder; } //指挥建造者创建产品的过程 public void construct(){ builder.buildPartA(); builder.buildPartB(); builder.buildPartC(); } } /** * 抽象建造者 */ interface Builder { //定义建造者职责:负责产品的具体部件 public void buildPartA(); public void buildPartB(); public void buildPartC(); /** * 建造者递交最终产品。产品的组装过程由指导类实现,从而解耦部件与过程 */ public Product getProduct(); } /** * 具体建造者M */ class BuilderImplM implements Builder{ private Product product = new Product(); @Override public void buildPartA() { product.setPart1("mmm"); System.out.println("M产品具体建造者构建A部件.."); } @Override public void buildPartB() { System.out.println("M产品具体建造者构建B部件.."); } @Override public void buildPartC() { System.out.println("M产品具体建造者构建C部件.."); } @Override public Product getProduct() { return product; } } /** * 具体建造者P */ class BuilderImplP implements Builder{ private Product product = new Product(); @Override public void buildPartA() { product.setPart1("ppp"); //System.out.println("P产品具体建造者构建A部件.."); } @Override public void buildPartB() { System.out.println("P产品具体建造者构建B部件.."); } @Override public void buildPartC() { System.out.println("P产品具体建造者构建C部件.."); } @Override public Product getProduct() { return product; } } /** * 产品 */ class Product { private String part1; private String part2; private String part3; //省略 get/set... } /** *@Author: April *@Date: 2014-3-17 */ public class Client { public static void main(String[] args) { //客户选择想要的产品(创建建造者对象) Builder builder=new BuilderImplP(); //交给指导类指挥 Director director=new Director(builder); //指导类指导建造者建造产品 director.construct(); //客户从建造者获取产品 Product product=builder.getProduct(); } }
理解建造者模式
- 建造者模式的功能
建造者模式的主要功能是构建复杂的产品,而且是细化的分步骤的构建产品。重在一步步解决构造复杂对象的问题。更重要的,构建过程是统一的、固定不变的,变化的部分放到建造者部分了,只要配置不同的建造者,那么同样的构建过程就能构建出不同的产品来。即重心(本质)在于分离构建算法和具体的构造实现, 从而使得构建算法可以重用。
- 建造者模式构成
- Director,负责整体的构建算法,而且是分步骤的来执行
- Builder接口,定义如何构建各个部件实现和装配部件到产品中
Director实现整体构建算法时,需要创建和组合具体部件的时候,会把这些功能通过委托,交给Builder去完成
-
建造者模式与抽象工厂模式
建造者模式与抽象工厂模式有点相似,但是建造者模式返回一个完整的复杂产品,而抽象工厂模式返回一系列相关的产品;在抽象工厂模式中,客户端通过选择具体工厂来生成所需对象,而在建造者模式中,客户端通过指定具体建造者类型并指导Director类如何去生成对象,侧重于一步步构造一个复杂对象,然后将结果返回。如果将抽象工厂模式看成一个汽车配件生产厂,生成不同类型的汽车配件,那么建造者模式就是一个汽车组装厂,通过对配件进行组装返回一辆完整的汽车
建造者模式的优点
- 松散耦合。使得产品的构建过程与具体产品的表现松散耦合,从而使得构建算法可以复用,具体产品也可以灵活、方便的扩展和切换
- 更好的复用。构建算法与具体产品实现的分离,使得构建算法可以复用,同样的具体产品的实现也可以复用,同一个产品的实现,可以配合不同的构建算法使用