0

0

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

高洛峰

高洛峰

发布时间:2017-01-20 09:18:17

|

1721人浏览过

|

来源于php中文网

原创

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 parts = new ArrayList();

    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 parts = new ArrayList();

    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 parts = new ArrayList();

    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模式的必要了。

更多 java设计模式之建造者模式学习相关文章请关注PHP中文网!

相关文章

java速学教程(入门到精通)
java速学教程(入门到精通)

java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

150

2025.12.31

php网站源码教程大全
php网站源码教程大全

本专题整合了php网站源码相关教程,阅读专题下面的文章了解更多详细内容。

88

2025.12.31

视频文件格式
视频文件格式

本专题整合了视频文件格式相关内容,阅读专题下面的文章了解更多详细内容。

90

2025.12.31

不受国内限制的浏览器大全
不受国内限制的浏览器大全

想找真正自由、无限制的上网体验?本合集精选2025年最开放、隐私强、访问无阻的浏览器App,涵盖Tor、Brave、Via、X浏览器、Mullvad等高自由度工具。支持自定义搜索引擎、广告拦截、隐身模式及全球网站无障碍访问,部分更具备防追踪、去谷歌化、双内核切换等高级功能。无论日常浏览、隐私保护还是突破地域限制,总有一款适合你!

61

2025.12.31

出现404解决方法大全
出现404解决方法大全

本专题整合了404错误解决方法大全,阅读专题下面的文章了解更多详细内容。

493

2025.12.31

html5怎么播放视频
html5怎么播放视频

想让网页流畅播放视频?本合集详解HTML5视频播放核心方法!涵盖<video>标签基础用法、多格式兼容(MP4/WebM/OGV)、自定义播放控件、响应式适配及常见浏览器兼容问题解决方案。无需插件,纯前端实现高清视频嵌入,助你快速打造现代化网页视频体验。

16

2025.12.31

关闭win10系统自动更新教程大全
关闭win10系统自动更新教程大全

本专题整合了关闭win10系统自动更新教程大全,阅读专题下面的文章了解更多详细内容。

12

2025.12.31

阻止电脑自动安装软件教程
阻止电脑自动安装软件教程

本专题整合了阻止电脑自动安装软件教程,阅读专题下面的文章了解更多详细教程。

5

2025.12.31

html5怎么使用
html5怎么使用

想快速上手HTML5开发?本合集为你整理最实用的HTML5使用指南!涵盖HTML5基础语法、主流框架(如Bootstrap、Vue、React)集成方法,以及无需安装、直接在线编辑运行的平台推荐(如CodePen、JSFiddle)。无论你是新手还是进阶开发者,都能轻松掌握HTML5网页制作、响应式布局与交互功能开发,零配置开启高效前端编程之旅!

2

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 2.2万人学习

C# 教程
C# 教程

共94课时 | 5.8万人学习

Java 教程
Java 教程

共578课时 | 40.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号