java设计模式之建造者模式学习

1 概述
建造者模式(Builder Pattern)主要用于“分步骤构建一个复杂的对象”,在这其中“分步骤”是一个稳定的算法,而复杂对象的各个部分则经常变化。因此, 建造者模式主要用来解决“对象部分”的需求变化。 这样可以对对象构造的过程进行更加精细的控制。

2 示例
以生产手机为例,每个手机分为屏幕Screen、CPU、Battery。现在要生产两种手机,苹果机和三星。

苹果:

代码如下:

package org.scott.builder.before.use;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Scott
 * @version 2013-11-20
 * @description
 */
public class ApplePhone {
    List<String> parts = new ArrayList<String>();

public void createCPU() {
        parts.add("CUP: Qualcomm");
    }

public void createScreen() {
        parts.add("SCREEN: JDI");
    }

public void createBattery() {
        parts.add("BATTERY: DeSai");
    }

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

三星:

代码如下:

package org.scott.builder.before.use;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Scott
 * @version 2013-11-20
 * @description
 */
public class SamsungPhone {
    List<String> parts = new ArrayList<String>();

public void createCPU() {
        parts.add("CUP: MTK");
    }

public void createScreen() {
        parts.add("SCREEN: Samsung");
    }

public void createBattery() {
        parts.add("BATTERY: DeSai");
    }

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

测试客户端:

代码如下:

package org.scott.builder.before.use;
/**
 * @author Scott
 * @version 2013-11-20
 * @description
 */
public class BuilerTest {
    private static ApplePhone iphone = new ApplePhone();
    private static SamsungPhone samPhone = new SamsungPhone();

public static void main(String args[]){
        iphone.createCPU();
        iphone.createScreen();
        iphone.createBattery();
        iphone.show();

samPhone.createCPU();
        samPhone.createScreen();
        samPhone.createBattery();
        samPhone.show();
    }
}

是不是发现个问题?那就是生产手机的每一道工序都是一样的,确切的说是工序名称一样,只是具体的每个工序的处理不同,工序是不变的,就这么几步,每道工序的具体处理是变化的,由此,我们可以把不变的抽取出来,以“不变应万变”,将变化的,交给具体的产品来做。
具体怎么做?这回的Builder模式派上用场了。

首先来个Phone的接口:

代码如下:

package org.scott.builder.after.use;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Scott
 * @version 2013-11-20
 * @description
 */
public abstract class Phone {
    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");
        }
    }
}

苹果手机类:

代码如下:

package org.scott.builder.after.use;
/**
 * @author Scott
 * @version 2013-11-20
 * @description
 */
public class ApplePhone extends Phone{

}

三星手机类:

代码如下:

package org.scott.builder.after.use;
/**
 * @author Scott
 * @version 2013-11-20
 * @description
 */
public class SamsungPhone extends Phone{

}

再定义个生产步骤的接口Builder:

代码如下:

package org.scott.builder.after.use;
/**
 * @author Scott
 * @version 2013-11-20
 * @description
 */
public interface Builder {
    public void buildCPU();

public void buildScreen();

public void buildBattery();

public Phone getPhone();
}

苹果手机的Builder:

代码如下:

package org.scott.builder.after.use;
/**
 * @author Scott
 * @version 2013-11-20
 * @description
 */
public class ApplePhoneBuilder implements Builder{
    private Phone phone = new ApplePhone();

@Override
    public void buildCPU() {
        phone.add("CUP: Qualcomm");
    }

@Override
    public void buildScreen() {
        phone.add("SCREEN: JDI");
    }

@Override
    public void buildBattery() {
        phone.add("BATTERY: DeSai");
    }

@Override
    public Phone getPhone() {
        return phone;
    }

}

三星手机的Builder:

代码如下:

package org.scott.builder.after.use;
/**
 * @author Scott
 * @version 2013-11-20
 * @description
 */
public class SamsungPhoneBuilder implements Builder{

private Phone phone = new SamsungPhone();

@Override
    public void buildCPU() {
        phone.add("CUP: MTK");       
    }

@Override
    public void buildScreen() {
        phone.add("SCREEN: Samsung");
    }

@Override
    public void buildBattery() {
        phone.add("BATTERY: DeSai");       
    }

@Override
    public Phone getPhone() {
        return phone;
    }

}

指导具体生产手机的Director:

代码如下:

package org.scott.builder.after.use;
/**
 * @author Scott
 * @version 2013-11-20
 * @description
 */
public class Director {
    private Builder builder;

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

public void construct(){
        builder.buildCPU();
        builder.buildScreen();
        builder.buildBattery();
    }
}

最后写个测试类:

代码如下:

package org.scott.builder.after.use;
/**
 * @author Scott
 * @version 2013-11-20
 * @description
 */
public class BuilderTest {

private static Builder iPhoneBuilder = new ApplePhoneBuilder();
    private static Builder samPhoneBuilder  = new SamsungPhoneBuilder();

public static void main(String[] args) {
        Director director = new Director(iPhoneBuilder);
        director.construct();
        Phone phone = iPhoneBuilder.getPhone();
        System.out.println("iphone");
        phone.show();

director = new Director(samPhoneBuilder);
        director.construct();
        phone = samPhoneBuilder.getPhone();
        System.out.println("\nsamSung");
        phone.show();
    }

}

运行结果:

代码如下:

iphone
产品部件信息:CUP: Qualcomm    SCREEN: JDI    BATTERY: DeSai   
samSung
产品部件信息:CUP: MTK    SCREEN: Samsung    BATTERY: DeSai

这里的两个Phone实体类是空的,如果是这种情况,那么它们可以省略掉,如果 Phone接口也可以被省略掉,最终剩下的就只有 Director、Builder、和具体的 Bulider 实现类。并且,ApplePhone类和 SamsungPhone类是有关系的两个类,它们不同的手机品牌,如果遇到两个或多个没有太多关系的类,公共的接口Phone就没有存在的必要,但是这时候,那么 Builder 接口的规定的 getPhone() 方法的返回值怎么确定呢?

  无论返回值类型是 ApplePhone还是SamsungPhone,都会产生问题,因为返回结果的类型不统一。此时,可以将 Phone定义成一个空接口(不包含任何方法的接口),再让这些没有相互关系的具体产品类都去实现这个接口,那么 Builder 接口里面规定的 getPhone() 方法的返回值类型依然是 Phone 类型,就解决问题了。不过这种情况下,也就没有使用Builder模式的必要了。

(0)

相关推荐

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

    Builder模式定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. Builder模式是一步一步创建一个复杂的对象,它允许用户可以只通过指定复杂对象的类型和内容就可以构建它们.用户不知道内部的具体构建细节.Builder模式是非常类似抽象工厂模式,细微的区别大概只有在反复使用中才能体会到. 为何使用建造者模式 是为了将构建复杂对象的过程和它的部件解耦.注意:是解耦过程和部件. 因为一个复杂的对象,不但有很多大量组成部分,如汽车,有很多部件:车轮.方向盘.发动机,还

  • Java设计模式之抽象工厂模式实例详解

    本文实例讲述了Java设计模式之抽象工厂模式.分享给大家供大家参考,具体如下: 具体工厂类:生产创建某一类具体产品对象. 抽象产品类可以使用接口或者父类来描述产品对象的行为特征. 具体产品类就是某一具体的对象. 那么抽象工厂模式和工厂模式的不同之处呢? 其实最大的不同就在于,在产品类的结构更加复杂时,抽象工厂模式针对不同的产品族(就是一类产品对象)定义了不同的行为,也就是在父类或接口中,定义了不同的产生方法.不同的产品族调用各自的创建方法.同时不同的产品族横向比较,也有可归类的相同特征,这些特征

  • 理解java设计模式之建造者模式

    建造者模式(Builder Pattern)主要用于"分步骤构建一个复杂的对象",在这其中"分步骤"是一个稳定的算法,而复杂对象的各个部分则经常变化.因此, 建造者模式主要用来解决"对象部分"的需求变化. 这样可以对对象构造的过程进行更加精细的控制. package com.shejimoshi.create.Builder; /** * 功能:意图是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示 * 适用性: * 当创

  • Java运用设计模式中的建造者模式构建项目的实例解析

    1.建造者模式概念 定义: 将一个复杂的对象构建与其表示相分离,使得同样的构建过程可以创建不同的表示: 核心 : 构建与表示分离,同构建不同表示 区别于 抽象工厂模式 : (1)与抽象工厂模式 相似,因为它也可以创建复杂对象.主要的区别是建造者模式着重于 一步步构造一个复杂对象,关注的是零件类型和装配工艺的顺序 .而抽象工厂模式着重于多个系列的产品对象(简单的或是复杂的).建造者模式在最后的一步返回产品,而对于抽象工厂来说,产品是立即返回的. (2)在建造者模式里,有个指导者,由指导者来管理建造

  • Java设计模式之责任链模式(Chain of Responsibility模式)介绍

    Chain of Responsibility定义:Chain of Responsibility(CoR) 是用一系列类(classes)试图处理一个请求request,这些类之间是一个松散的耦合,唯一共同点是在他们之间传递request.也就是说,来了一个请求,A类先处理,如果没有处理,就传递到B类处理,如果没有处理,就传递到C类处理,就这样象一个链条(chain)一样传递下去. 如何使用责任链模式 虽然这一段是如何使用CoR,但是也是演示什么是CoR. 有一个Handler接口: 复制代码

  • Java设计模式之建造者模式实例详解

    本文实例讲述了Java设计模式之建造者模式.分享给大家供大家参考,具体如下: 建造者模式(builder)可以将部件和其组装过程分开.一步一步创建一个复杂的对象. 用户只需要指定复杂对象的类型就可以得到该对象,而无须知道其内部的具体构造细节. 什么情况下会用到建造者模式? 个人理解,当我们创建的对象在创建时需要逻辑的时候. 比如,一个简单的pojo对象,我们想要创建,直接就可以new出来,没有什么逻辑. 当有一个复杂的对象,你想要创建它时,它的各个属性之间是有逻辑关系的. 一个属性赋值取值依赖于

  • Java设计模式之装饰者模式详解和代码实例

    装饰者模式可以给已经存在的对象动态的添加能力.下面,我将会用一个简单的例子来演示一下如何在程序当中使用装饰者模式. 1.装饰者模式 让我们来假设一下,你正在寻找一个女朋友.有很多来自不同国家的女孩,比如:美国,中国,日本,法国等等,他们每个人都有不一样的个性和兴趣爱好,如果需要在程序当中模拟这么一种情况的话,假设每一个女孩就是一个Java类的话,那么就会有成千上万的类,这样子就会造成类的膨胀,而且这样的设计的可扩展性会比较差.因为如果我们需要一个新的女孩,就需要创建一个新的Java类,这实际上也

  • 深入解析Java的设计模式编程中建造者模式的运用

    定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 类型:创建类模式 类图: 四个要素 产品类:一般是一个较为复杂的对象,也就是说创建对象的过程比较复杂,一般会有比较多的代码量.在本类图中,产品类是一个具体的类,而非抽象类.实际编程中,产品类可以是由一个抽象类与它的不同实现组成,也可以是由多个抽象类与他们的实现组成. 抽象建造者:引入抽象建造者的目的,是为了将建造的具体过程交与它的子类来实现.这样更容易扩展.一般至少会有两个抽象方法,一个用来建造产品,一个是用来返回

  • java设计模式之工厂模式实例详解

    本文实例讲述了java设计模式之工厂模式.分享给大家供大家参考,具体如下: 工厂模式(factory) 涉及到4个角色:抽象工厂类角色,具体工厂类角色,抽象产品类角色和具体产品类角色. 抽象工厂类角色使用接口或者父类来描述工厂的行为, 具体工厂类角色负责创建某一类型的产品对象. 抽象产品类可以使用接口或者父类来描述产品对象的行为特征. 具体产品类就是某一具体的对象. 工厂模式不同于静态工厂模式的地方: 工厂模式在工厂类也实现了多态,而不仅仅是在产品对象上实现多态. 它可以应对不同类型的产品对应一

  • Java设计模式之单例模式实例详解【懒汉式与饿汉式】

    本文实例讲述了Java设计模式之单例模式.分享给大家供大家参考,具体如下: 单例模式就是产生一个对象实例,供外外部访问. 它的应用场景就是在这个类在全局真资源需要统一访问,否则会造成混乱时,才有必要设计成单例. 懒汉式,就是在使用这个对象时,才去查看这个对象是否创建,如果没创建就马上创建,如果已经创建,就返回这个实例. 饿汉式,在加载这个类的时候就先创建好一个对象实例,等待调用. 两者的优缺点也能猜到,使用懒汉式,在反应速度上肯定要比饿汉式慢. 但是这个对象如果不被调用,那就节省了cpu和内存资

随机推荐