在上篇文章中,对Java Builder模式的使用体验主要是从Builder对构造器改造方面的优秀特性来说的,感觉并没有从Java Builder模式本身的功能和作用去写,因此决定再从Builder模式的作用以及在项目开发中的使用来体验下。
Builder 模式,即建造者模式,顾名思义,这个模式可能更多的使用在产品的组装中使用,具体说就是在软件产品的组件或模块组装的时候使用。
感觉网络上比较好的解释有:
建造者模式(Builder):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
适用的场景:
1、当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
2、当构造过程必须允许被构造的对象有不同的表示时。
首先我们来说下,建造者模式中三个重要的角色:
1、Product (生产者):该角色其实类似于工厂里的流水线,它可以生产各种各样的组件,但是并不知道怎样将这些组件进行组装,进而产生出不同的产品。
2、Builder(建造者):该角色类似流水线上的操作工人,它负责将不同的流水线上生产出的不同零件或组件,按照(领导Director)特定要求组装成特定的产品,并给Director提供一个build方法,让其随时可以取走已经组装好的产品。
3、Director(指挥者或者领导):该角色主要根据不同客户的需求,调用不同的Builder对象来组装出特定的产品,提供给客户使用。
为了便于理解,我们假设还有第4个角色:
4、Client(客户): 客户是产品需求的来源,但是客户不会和生产线或工厂的操作工打交道,他们只会开着车,和领导打交道。
好了,各个角色,我们都定义好了,我们寻找一个场景吧。就拿汽车的生产来说事吧。
我们假设有以下场景:
Dirctor是生产CarX品牌汽车公司的领导,ClientA和ClientB是分别来自欧洲和亚洲的客户。ClientA希望买到的CarX汽车能够达到更好的节能和经济性需求,ClientB希望买到的车更好的满足安全性和舒适性。Dirctor根据2个客户的需求,命令工程师设计了2套流水线,2条流水线生产的产品都一样,但是产品的性能不同:
A生产线(ProductionLineA)主要生产小排量的发动机和配置不高的ABS安全系统;
B生产线(ProductionLineB)主要生产排量较大的发动机和配置较高的ABS安全系统;
同时为2条生产线安排了不同的组装工程师BuilderA和BuilderB。
产品的组装命令和验收由Dirctor统一负责。
好了,自此,任务分配完毕,我们开始编码工作了。
首先,对上面问题的分析,我们可以发现,A生产线和B生产线生产的东西名称和功能是一样的,只是性能不同,因此可以对生产线可以进行抽象。
package com.icecode.demo;
public abstract class AbstractProductionLine {
//生产汽车发动机
public abstract void createEngine();
//生产汽车安全系统
public abstract void createSecuritySystem();
//生产汽车车身
public abstract void createCarBody();
}
同样,我们也可以对建造工程师也进行抽象,如下:
package com.icecode.demo;
public abstract class AbstractBuilder {
//命令1:启动生产汽车零部件生产线命令
public abstract void buildCarParts();
//命令2:将命令1生产的零部件组装成完整的汽车
public abstract AbstractProductionLine buildCar();
}
好了,方案和任务都安排好了,我们开始具体实施了。
package com.icecode.demo.impl;
import com.icecode.demo.AbstractProductLine;
/**
* 流水线A
* @author zhanche
*
*/
public class ConcreteProductLineA extends AbstractProductLine {
@Override
public void createEngine() {
System.out.println("------------生产小排量发动机----------");
}
@Override
public void createSecuritySystem() {
System.out.println("----------生产普通标准的安全系统-----------");
}
@Override
public void createCarBody() {
System.out.println("----------生成汽车车身部件-----------");
}
}
package com.icecode.demo.impl;
import com.icecode.demo.AbstractProductLine;
/**
* 流水线B
* @author zhanche
*
*/
public class ConcreteProductLineB extends AbstractProductLine {
@Override
public void createEngine() {
System.out.println("------------生产标准排量的发动机----------");
}
@Override
public void createSecuritySystem() {
System.out.println("----------生产高标准的安全系统-----------");
}
@Override
public void createCarBody() {
System.out.println("----------生成汽车车身部件-----------");
}
}
package com.icecode.demo.impl;
import com.icecode.demo.AbstractBuilder;
import com.icecode.demo.AbstractProductLine;
/**
* 建造工人A
* @author zhanche
*
*/
public class ConcreteBuilderA extends AbstractBuilder {
private AbstractProductLine productLineA = new ConcreteProductLineA();
@Override
public void buildCarParts() {
productLineA.createEngine();
productLineA.createSecuritySystem();
productLineA.createCarBody();
System.out.println("-----生产线A完成一辆汽车零部件的生产-----");
}
@Override
public AbstractProductLine buildCar() {
System.out.println("----------完成一辆汽车A的组装调试----------");
return productLineA;
}
}
package com.icecode.demo.impl;
import com.icecode.demo.AbstractBuilder;
import com.icecode.demo.AbstractProductLine;
/**
* 建造工人B
* @author zhanche
*
*/
public class ConcreteBuilderB extends AbstractBuilder {
private AbstractProductLine productLineB = new ConcreteProductLineB();
@Override
public void buildCarParts() {
productLineB.createEngine();
productLineB.createSecuritySystem();
productLineB.createCarBody();
System.out.println("-----生产线B完成一辆汽车零部件的生产----");
}
@Override
public AbstractProductLine buildCar() {
System.out.println("----------完成一辆汽车B的组装调试----------");
return productLineB;
}
}
到此,我们的产品建造实施实体都安排好了,现在需要做的是实现Director(领导者)角色的功能,他负责下发开始启动生产零部件的命令和开始组装的命令。
package com.icecode.demo.director;
import com.icecode.demo.AbstractBuilder;
import com.icecode.demo.AbstractProductLine;
import com.icecode.demo.impl.ConcreteBuilderA;
import com.icecode.demo.impl.ConcreteBuilderB;
public class Director {
private AbstractBuilder builderA = new ConcreteBuilderA();
private AbstractBuilder builderB = new ConcreteBuilderB();
public AbstractProductLine getProductA() {
builderA.buildCarParts();
//还可以增加对产品质量抽检等功能
return builderA.buildCar();
}
public AbstractProductLine getProductB(){
builderB.buildCarParts();
//还可以增加对产品质量抽检等功能
return builderB.buildCar();
}
}
领导的任务和职责也安排好了,现在2个客户ClientA和ClientB来和Director签订合同,CarX工厂开始完成客户的任务。代码如下:
package com.icecode.demo.client;
import com.icecode.demo.director.Director;
/**
* 客户A
* @author zhanche
*
*/
public class ClientA {
/**
* @param args
*/
public static void main(String[] args) {
System.out.println("ClientA 完成与Director生产汽车A的合同");
Director director = new Director();
director.getProductA();
}
}
package com.icecode.demo.client;
import com.icecode.demo.director.Director;
/**
* 客户B
* @author zhanche
*
*/
public class ClientB {
/**
* @param args
*/
public static void main(String[] args) {
System.out.println("ClientB 完成与Director生产汽车A的合同");
Director director = new Director();
director.getProductB();
}
}
运行ClientA输出如下结果:
ClientA 完成与Director生产汽车A的合同
------------生产小排量发动机----------
----------生产普通标准的安全系统-----------
----------生成汽车车身部件-----------
----生产线A完成一辆汽车零部件的生产------
----------完成一辆汽车A的组装调试----------
运行ClientB输出如下结果:
ClientB 完成与Director生产汽车A的合同
------------生产标准排量的发动机----------
----------生产高标准的安全系统-----------
----------生成汽车车身部件-----------
-----生产线B完成一辆汽车零部件的生产----
----------完成一辆汽车B的组装调试----------
到此为止,我们的一个建造者模式的应用实例已经完成了。当然,对生产线和建造者的抽象还可以使用接口来实现,原理都是一样的。
有人总结说Builder模式其实综合了模板方法和工厂模式的思想,其实的确可以这么理解,只是建造者模式对工厂化的生产过程和参与者的角色,做了进一步的细化。大家可以根据不同的需求,选择不同的设计模式。
分享到:
相关推荐
设计模式之 Template(模板方法) 实际上向你介绍了为什么要使用 Java 抽象类,该模式原理简单,使用很普遍. 设计模式之 Strategy(策略) 不同算法各自封装,用户端可随意挑选需要的算法. 设计模式之 Chain of ...
抽象包括两个方面,一是过程抽象,二是数据抽象。 2.继承: 继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类...
抽象包括两个方面,一是过程抽象,二是数据抽象。 2.继承: 继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承...
:grinning_face:点击查看电子书,体验更好 :backhand_index_pointing_right: 创建型 (Creational)Java Kotlin结构型(Structural)适配器模式(Adapter Class/Object Pattern) Java桥接模式(Bridge Pattern) ...
ASP.NET 2.0使用Web Part创建应用程序之二(共二) 体验 .net2.0 的优雅(2) -- ASP.net 主题和皮肤 NET2.0系列介绍(一).NET 2.0 中Web 应用程序主题的切换 ASP.NET 2.0 中Web 应用程序主题的切换 2.0正式版中...
,lyadmin全称零云lyadmin是一套轻量级通用后台,采用JFinal+Vue+Element制作,内置系统设置、上传管理、权限管理、模块管理、插件管理等功能,独有的Builder页面自动生成技术节省50%开发成本 微信小程序是腾讯公司...
目录页 下一页 ... 虽然 PHP5 还没有正式发布(开发版本已经提供下载),但我们现在就可以开始体验一下新的版本将要带给我们的惊喜。...这三大特点为: * 新的对象模式 (New ...Power by Softscape HTML Builder 3
// 注册autofac打标签模式builder.RegisterModule(new AutofacAnnotationModule(typeof(AnotationTest).Assembly));//如果需要开启支持循环注入//builder.RegisterModule(new AutofacAnnotationModule(typeof(Ano
第二章 多窗口类浏览器设计 11 2.1 多窗口类浏览器需求分析 11 2.1.1 Activity简介 11 2.1.2 Fragment简介 11 2.1.3 多窗口类浏览器需求 12 2.2 多窗口浏览器模式的实现机制 12 2.2.1安卓移动端多窗口浏览器框架 12 ...
Visual SiteBuilder网站综合管理平台(简称VSB)是基于JAVA技术开发的网站管理软件。该系统融合先进的网站建设周期管理思想,集成网站可视化设计,内容管理,虚拟主机,用户管理,审核管理等经典应用,全面覆盖了...
5、报表数据来源丰富:支持绑定(报表数据拉模式)与非绑定(报表数据推模式),一切数据库数据与其它数据都可以作为报表数据源。 6、提供图表功能,包括:饼图、叠加饼图、柱状图、气泡图、折线图、曲线图、散列点图等...
5、报表数据来源丰富:支持绑定(报表数据拉模式)与非绑定(报表数据推模式),一切数据库数据与其它数据都可以作为报表数据源。 6、提供图表功能,包括:饼图、叠加饼图、柱状图、气泡图、折线图、曲线图、散列点图等...
5、报表数据来源丰富:支持绑定(报表数据拉模式)与非绑定(报表数据推模式),一切数据库数据与其它数据都可以作为报表数据源。 6、提供图表功能,包括:饼图、叠加饼图、柱状图、气泡图、折线图、曲线图、散列点图等...
5、报表数据来源丰富:支持绑定(报表数据拉模式)与非绑定(报表数据推模式),一切数据库数据与其它数据都可以作为报表数据源。 6、提供图表功能,包括:饼图、叠加饼图、柱状图、气泡图、折线图、曲线图、散列点图等...
5、报表数据来源丰富:支持绑定(报表数据拉模式)与非绑定(报表数据推模式),一切数据库数据与其它数据都可以作为报表数据源。 6、提供图表功能,包括:饼图、叠加饼图、柱状图、气泡图、折线图、曲线图、散列点图等...
Builder 模式来创建,使用方式就和 Android 里面的AlertDialog一样,通过 Builder 去构建一个 PageLayout。最后的样子是长这样的:方法注释showLoading()显示 loadingshowError()显示错误布局showEmpty()显示空布局...
25.4.4 Gestures Builder应用程序 25.5 参考资料 25.6 小结 第26章 传感器 26.1 什么是传感器 26.1.1 检测传感器 26.1.2 可以了解的传感器信息 26.2 获取传感器事件 26.3 解释传感器数据 ...
25.4.4 Gestures Builder应用程序 25.5 参考资料 25.6 小结 第26章 传感器 26.1 什么是传感器 26.1.1 检测传感器 26.1.2 可以了解的传感器信息 26.2 获取传感器事件 26.3 解释传感器数据 ...
Support auto resize images. 具有特殊的对话框 <br/>With Style builder dialog box you can apply CSS style attributes directly to any HTML elements on your Web page.<br/> <br/> 支持内容...