关闭

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

标签: androidjava设计模式
663人阅读 评论(1) 收藏 举报
分类:

最近在看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 类型,这样一来问题就解决了。

2
0
查看评论

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

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

浅谈JAVA设计模式之——建造者模式(Builder)

一、概述 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。 二、适用性 1.当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。 2.当构造过程必须允许被构造的对象有不同的表示时。 三、参与者 1.Builder 为创建一个Product对象的各个部件指...
  • l1028386804
  • l1028386804
  • 2015-05-02 21:22
  • 9781

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

建造者模式:是将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。  建造者模式通常包括下几个角色: 1. builder(抽象建造者):给出一个抽象结论,以规范产品对象的各个组成成分的建造。这个接口规定要实现复杂对象的那些部分的创建,并不涉及具体的对象部件的创建。 2...
  • u013256816
  • u013256816
  • 2016-03-25 11:18
  • 2063

Android设计模式之建造者模式(builder pattern)

builder设计模式我们很常见,比如我们使用AlertDialog的时候就使用的builder设计模式,著名的Universal-Image-Loader的初始化配置也是使用的builder设计模式,那么他们为什么使用builder设计模式,什么情况下我们应该考虑使用builder设计模式,这是我...
  • nugongahou110
  • nugongahou110
  • 2015-12-25 10:08
  • 2943

设计模式(创建型)之建造者模式(Builder Pattern)

建造者模式将客户端与包含多个组成部分的复杂对象的创建过程分离,客户端压根不用知道复杂对象的内部组成部分与装配方式,只需要知道所需建造者的类型即可。它关注如何一步一步创建一个的复杂对象,不同的具体建造者定义了不同的创建过程,且具体建造者相互独立,增加新的建造者非常方便。
  • yanbober
  • yanbober
  • 2015-04-28 16:38
  • 4448

GOF设计模式-建造者模式(builder)

建造者模式(builder),将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。Dirextor: 指挥者类,用于统一组装流程 Builder:抽象Builder类,规范产品的组建,一般是由子类实现。 DFCarBuilder: 抽象Builder类的实现类,实现抽象Buil...
  • mzh1992
  • mzh1992
  • 2017-02-16 13:39
  • 106

java/android 设计模式学习笔记(10)---建造者模式

这篇博客我们来介绍一下建造者模式(Builder Pattern),建造者模式又被称为生成器模式,是创造性模式之一,与[工厂方法模式](http://blog.csdn.net/self_study/article/details/51419770)和[抽象工厂模式](http://blog.csd...
  • zhao_zepeng
  • zhao_zepeng
  • 2016-06-19 21:00
  • 8378

Java实现(04)——建造者模式(Builder Pattern)

建造者模式一步一步地通过简单的对象创建复杂的对象。 本例介绍快餐店中的快餐,快餐有汉堡和饮料,汉堡分为蔬菜汉堡和肌肉汉堡,饮料分为百事和可口可乐。汉堡需要盒子来装,可乐需要瓶子。通过创建一个Meal类来表示点的快餐。 创建食物以及包装
  • WAN_EXE
  • WAN_EXE
  • 2016-12-06 09:22
  • 414

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

一、概述 二、适用
  • l416112167
  • l416112167
  • 2014-10-31 01:15
  • 3595

设计模式系列(四)建造者模式Builder

建造者模式将一个复杂对象的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。 Builder:为创建Product对象的各个部件指定抽象接口。 ConcreteBuilder:实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,并提供一个检索产品的接口。 Dire...
  • robertcpp
  • robertcpp
  • 2016-06-26 14:51
  • 2513
    个人资料
    • 访问:180873次
    • 积分:2148
    • 等级:
    • 排名:千里之外
    • 原创:46篇
    • 转载:8篇
    • 译文:0篇
    • 评论:52条
    写给自己
    在找到你的爱情以前
    我们的感情在流浪
    在找到你的团队以前
    我们的梦想在流浪

    没有人愿意选择奔波
    但是努力更让人踏实
    联系方式
    QQ:491150376

    打个广告,吉林长春,优格实战学院,招生啦,由多年一线工作经验的讲师授课,主打实战。
    培训课程包括Java,Web前端,Android,iOS,UI,产品,测试,欢迎大家咨询!
    博客专栏