设计模式:Java 建造者模式(Builder)

转载 2015年11月19日 09:49:02

最近在看Android的源码,发现里面有很多设计模式,而这块也正是我所欠缺的。一边查一边学一边看。

下面整理一下:
Builder 模式 —— 建造者模式(又译成生成器模式)的主要功能是构建复杂的产品,它是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

举个例子,打个生产电脑的比方,这里简单一点,假设生产电脑只需要 CUP、内存和显卡,现在需要生产宏基和戴尔两个品牌的电脑,不用设计模式的实现:

Acer.java

import java.util.ArrayList;
import java.util.List;
/**
 * -----------------------------------------
 * @描述  生产宏基笔记本电脑
 * @作者  ADong
 * @邮箱  goodhaidong@163.com
 * @日期  2015-11-19 
 * -----------------------------------------
 */
public class Acer{

    protected List<String> parts = new ArrayList<String>();

    //生产CPU
    public void createCPU() {

        parts.add("CUP: Intel 酷睿i3 2350M");
    }

    //生产内存
    public void createMemory() {

        parts.add("内存: 4GB DDR3 1333MHz");
    }

    //生产显卡
    public void createDisplayCard() {

        parts.add("显卡: NVIDIA GeForce GT 520M");
    }

    //显示产品信息
    public void show(){
        System.out.print("产品部件信息:");
        for(String part : parts){
            System.out.print(part + "\t");
        }
    }

}

Dell.java

import java.util.ArrayList;
import java.util.List;
/**
 * -----------------------------------------
 * @描述  生产戴尔笔记本电脑
 * @作者  ADong
 * @邮箱  goodhaidong@163.com
 * @日期  2015-11-19 
 * -----------------------------------------
 */
public class Dell{

    protected List<String> parts = new ArrayList<String>();

    //生产CPU
    public void createCPU() {

        parts.add("CUP: Intel 酷睿i7 3612QM");
    }

    //生产内存
    public void createMemory() {

        parts.add("内存: 8GB DDR3 1600MHz");
    }

    //生产显卡
    public void createDisplayCard() {

        parts.add("显卡: NVIDIA GeForce GT 640M+Intel GMA HD 4000");
    }

    //显示产品信息
    public void show(){
        System.out.print("产品部件信息:");
        for(String part : parts){
            System.out.print(part + "\t");
        }
    }

}

Client.java

/**
 * -----------------------------------------
 * @描述  客户端测试
 * @作者  ADong
 * @邮箱  goodhaidong@163.com
 * @日期  2015-11-19 
 * -----------------------------------------
 */
public class Client {

    private static Acer acer = new Acer();
    private static Dell dell = new Dell();

    public static void main(String[] args){

        /**
         * 宏基
         */
        acer.createCPU();
        acer.createMemory();
        acer.createDisplayCard();
        acer.show();

        /***************************************/
        System.out.println();
        /***************************************/

        /**
         * 戴尔
         */
        dell.createCPU();
        dell.createMemory();
        dell.createDisplayCard();
        dell.show();
    }

}

仔细观察一下上面的实现,不难发现,不管是生产何种品牌的笔记本,在实现的时候,它们的步骤基本上都是一样的,都是生产电脑相应的部件并添加都电脑里面,在生产不同品牌电脑

的时候,都会重复处理这几个步骤,但是明显的是,这几个步骤都是稳定的或者说是一样的,只是每个步骤的具体实现不一样或者说是变化的,如果将这些变化的部分抽取出来,也就是

说如果将处理过程与具体的步骤的实现分离开来的话,这样就能够复用这些处理过程,而且这样一来就能很容易的做到在不同品牌电脑之间切换生产。

使用 Builder 模式的实现,如图:
Builder 模式的实现

Product.java

package pattern.builder;

import java.util.ArrayList;
import java.util.List;
/**
 * -----------------------------------------
 * @描述  抽象产品
 * @作者  ADong
 * @邮箱  goodhaidong@163.com
 * @日期  2015-11-19
 * -----------------------------------------
 */
public abstract class Product {

    protected List<String> parts = new ArrayList<String>();

    //添加部件
    public void add(String part){
        parts.add(part);
    }

    //显示产品信息
    public void show(){
        System.out.print("产品部件信息:");
        for(String part : parts){
            System.out.print(part + "\t");
        }
    }
}

Acer.java

package pattern.builder;
/**
 * -----------------------------------------
 * @描述  宏基笔记本
 * @作者  ADong
 * @邮箱  goodhaidong@163.com
 * @日期  2015-11-19
 * -----------------------------------------
 */
public class Acer extends Product{

    //Do other things here

}

Dell.java

package pattern.builder;
/**
 * -----------------------------------------
 * @描述  戴尔笔记本
 * @作者  ADong
 * @邮箱  goodhaidong@163.com
 * @日期  2015-11-19
 * -----------------------------------------
 */
public class Dell extends Product{

    //Do other things here

}

Builder.java

package pattern.builder;
/**
 * -----------------------------------------
 * @描述  抽象建造者
 * @作者  ADong
 * @邮箱  goodhaidong@163.com
 * @日期  2015-01--11-19
 * -----------------------------------------
 */
public interface Builder {

    //CUP
    public void buildCPU();

    //内存
    public void buildMemory();

    //显卡
    public void buildDisplayCard ();

    //最终产品
    public Product getFinalResult();

}

AcerBuilder.java

package pattern.builder;
/**
 * -----------------------------------------
 * @描述  宏基笔记本建造者
 * @作者  ADong
 * @邮箱  goodhaidong@163.com
 * @日期  2015-11-19
 * -----------------------------------------
 */
public class AcerBuilder implements Builder {

    private Product product = new Acer();

    @Override
    public void buildCPU() {

        product.add("CUP: Intel 酷睿i3 2350M");
    }

    @Override
    public void buildMemory() {

        product.add("内存: 4GB DDR3 1333MHz");
    }

    @Override
    public void buildDisplayCard() {

        product.add("显卡: NVIDIA GeForce GT 520M");
    }

    @Override
    public Product getFinalResult() {

        return product;
    }

}

DellBuilder.java

package pattern.builder;
/**
 * -----------------------------------------
 * @描述  戴尔笔记本建造者
 * @作者  ADong
 * @邮箱  goodhaidong@163.com
 * @日期  2015-11-19
 * -----------------------------------------
 */
public class DellBuilder implements Builder {

    private Product product = new Dell();

    @Override
    public void buildCPU() {

        product.add("CUP: Intel 酷睿i7 3612QM");
    }

    @Override
    public void buildMemory() {

        product.add("内存: 8GB DDR3 1600MHz");
    }

    @Override
    public void buildDisplayCard() {

        product.add("显卡: NVIDIA GeForce GT 640M+Intel GMA HD 4000");
    }

    @Override
    public Product getFinalResult() {

        return product;
    }

}

Director.java

package pattern.builder;
/**
 * -----------------------------------------
 * @描述  产品构建指导者
 * @作者  ADong
 * @邮箱  goodhaidong@163.com
 * @日期  2015-11-19
 * -----------------------------------------
 */
public class Director {

    private Builder builder;

    public Director(Builder builder){
        this.builder = builder;
    }

    public void construct(){

        builder.buildCPU();
        builder.buildMemory();
        builder.buildDisplayCard();
    }
}

Client.java

package pattern.builder;
/**
 * -----------------------------------------
 * @描述  客户端测试
 * @作者  ADong
 * @邮箱  goodhaidong@163.com
 * @日期  2015-11-19
 * -----------------------------------------
 */
public class Client {

    private static Builder acerBuilder = new AcerBuilder(),
                                                dellBuilder  = new DellBuilder();

    public static void main(String[] args){

        System.out.print("宏基");
        Director director = new Director(acerBuilder);
        director.construct();
        Product product = acerBuilder.getFinalResult();
        product.show();

        /***************************************/
        System.out.println();
        /***************************************/

        System.out.print("戴尔");
        director = new Director(dellBuilder);
        director.construct();
        product = dellBuilder.getFinalResult();
        product.show();
    }       
}

后台输出:
宏基产品部件信息:CUP: Intel 酷睿i3 2350M 内存: 4GB DDR3 1333MHz 显卡: NVIDIA GeForce GT 520M
戴尔产品部件信息:CUP: Intel 酷睿i7 3612QM 内存: 8GB DDR3 1600MHz 显卡: NVIDIA GeForce GT 640M+Intel GMA HD 4000

在这里,Acer 类和 Dell 类是空的,如果是这种情况,那么它们可以省略掉,如果 Product 也不是最终想要的,那么它也可以被省略掉,最终剩下的就只有 Director、Builder、

和具体的 Bulider 实现类。

在这里,Acer 类和 Dell 类是有关系的两个类,它们都是电脑的品牌之一,如果遇到两个或多个没有太多关系的类,假设 Acer 类代表电脑,Dell 类代表汽车,很明显,Acer 类和

Dell 类就不应该再有共同的父类,也就是这种情况下,Product 这个抽象类不存在了,这时候问题就来了,那么 Builder 接口的规定的 getFinalResult() 方法的返回值怎么确定呢??

如果它的返回值类型是 Acer,那么 DellBuilder 类就会有问题,如果它的返回值类型是 Dell,那么 AcerBuilder 类就会有问题;

很明显,这是由于类型不能正确匹配引起的,如果是这种情况,可以将 Product 设计成标识接口(空接口,接口里面没有规定任何行为方法),再让这些没有相互关系的具体产品类

都去实现这个接口,那么 Builder 接口里面规定的 getFinalResult() 方法的返回值类型依然是 Product 类型,这样一来问题就解决了。

相关文章推荐

设计模式:Android AlertDialog的builder(建造者模式)

最近,公司一个大牛问了个问题,Android中的AlertDialog的创建方法AlertDialog.Builder 是什么形式,有什么好处? 所以,最近一直都在看设计模式。 然后自己一点总结,...

设计模式(三)----- 建造者模式(Builder)----(JAVA版)

将一个复杂对象的构建与它的表示分离,使同样的构建过程可以创建不同的表示。可以将建造模式的精髓概括为:将构造复杂对象的过程和对象的部件解耦。这是对降低耦合、提高可复用性精神的一种贯彻。其实这种精神贯彻在...

Java设计模式--建造者模式【Builder Pattern】

昨晚回到家里,我爸爸气冲冲地跟我诉苦,“哎!,干个装修容易么?顾客啥都不懂,还非得规定装修顺序,要先贴地板砖后刷墙,到时候贴好的地砖上全是泥,哪有这么干活的?”老爸干了一辈子的装修,一切事宜由他全权负...

JAVA设计模式之 建造者模式【Builder Pattern】

一、概述 二、适用

java设计模式4--建造者模式(Builder)

本文地址:http://www.cnblogs.com/archimedes/p/java-builder-pattern.html,转载请注明源地址。 建造者模式 将一个复杂对象的构建与它的...

Java设计模式之建造者(Builder)模式

Java设计模式之建造者(Builder)模式 建造者模式介绍: Builder模式是一步一步创建一个复杂对象的创建性模式,它允许用户在不知道内部构建细节的情况下,可以更精细的控制对象的构造...

【java设计模式】之 建造者(Builder)模式

我们还是举上一节的例子:生产汽车。上一节我们通过模板方法模式控制汽车跑起来的动作,那么需求是无止境的,现在如果老板又增加了额外的需求:汽车启动、停止、鸣笛引擎声都由客户自己控制,他想要什么顺序就什么顺...

Java设计模式----建造者模式(Builder)

1.定义:    将一个复杂对象的创建与它的表示分离,这样可以使得同样的创建方式来构建不同的表示 2. 建造者模式通常包含4中元素:    1.  Builder :抽象的接口,称为抽象建造...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)