一、定义

将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。

二、使用范围

1.创建一个复杂的对象,他有多个不同的模块组成,其中有些模块不会改变,但是其他模块可能经常发生改变,我们不得已需要把不变的模块与常变的模块分开实现时。

2.当构造过程必须允许被构造的对象有不同表示时。

三、功能实现角色

1.builder:为创建一个产品对象的各个部件指定抽象接口。

2.ConcreteBuilder:实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,并 提供一个检索产品的接口。

3.Director:构造一个使用Builder接口的对象。

4.Product:表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,包括将这些部件装配成最终产品的接口。

四、实践

1.情景假设

我们在计费的过程中有一个计费模式获取类,他的功能是获取当前这个用户所需要的计费模式,但是计费有很多种,比如SMS计费(短信计费)、Cash计费(银行卡计费),其中SMS计费又包括中国移动、中国联通、印尼Tsel、印尼isat计费,Cash包括招商银行、农行、印尼Visa等,且不同支付方式给予不同的计费点和订单开头。在国外用户和国内用户时,要提供不同的计费集。

2.当前计费信息接口

public interface FeeInterf {public String orderNo();//当前交易编号public FeeTypeInterf feeType();//当前交易类型public float price();//当前交易金额
}

3.当前计费类型接口

public interface FeeTypeInterf {public String feeType();
}

4.当前计费类型的实现类

SMSFeeType

import cn.yzstu.buldermodule.interf.FeeTypeInterf;/*** 类描述** @author: 12405* @date: 2020/3/25-22:28*/
public class SMSFeeType implements FeeTypeInterf {@Overridepublic String feeType() {return "SMS";}
}

CashFeeType

import cn.yzstu.buldermodule.interf.FeeTypeInterf;/*** 类描述** @author: 12405* @date: 2020/3/25-22:29*/
public class CashFeeType implements FeeTypeInterf {@Overridepublic String feeType() {return "Cash";}
}

5.不同类型计费的实现类

SMS

import cn.yzstu.buldermodule.impl.feetype.SMSFeeType;
import cn.yzstu.buldermodule.interf.FeeInterf;
import cn.yzstu.buldermodule.interf.FeeTypeInterf;/*** 类描述** @author: 12405* @date: 2020/3/25-22:37*/
public abstract class SMSFee implements FeeInterf {@Overridepublic FeeTypeInterf feeType() {return new SMSFeeType();}
}

Cash

import cn.yzstu.buldermodule.impl.feetype.CashFeeType;
import cn.yzstu.buldermodule.interf.FeeInterf;
import cn.yzstu.buldermodule.interf.FeeTypeInterf;/*** 类描述** @author: 12405* @date: 2020/3/25-22:44*/
public abstract class CashFee implements FeeInterf {@Overridepublic FeeTypeInterf feeType() {return new CashFeeType();}
}

6.计费的详细实体类

中国移动

import java.util.UUID;/*** 类描述** @author: 12405* @date: 2020/3/25-22:49*/
public class ChinaMobileFee extends SMSFee {@Overridepublic String orderNo() {return "MOBL"+ UUID.randomUUID();}@Overridepublic float price() {return 10.0f;}
}

中国联通

import java.util.UUID;/*** 类描述** @author: 12405* @date: 2020/3/25-22:52*/
public class ChinaUnicomFee extends SMSFee{@Overridepublic String orderNo() {return "UNC"+ UUID.randomUUID();}@Overridepublic float price() {return 20.0f;}
}

印尼TSEl

import java.util.UUID;/*** 类描述** @author: 12405* @date: 2020/3/25-22:56*/
public class IndoTselFee extends SMSFee {@Overridepublic String orderNo() {return "TSEL"+ UUID.randomUUID();}@Overridepublic float price() {return 2000.0f;}
}

印尼ISAT

import java.util.UUID;/*** 类描述** @author: 12405* @date: 2020/3/25-22:57*/
public class IndoIsatFee extends SMSFee {@Overridepublic String orderNo() {return "ISAT"+ UUID.randomUUID();}@Overridepublic float price() {return 1000.0f;}
}

招商银行

import java.util.UUID;/*** 类描述** @author: 12405* @date: 2020/3/25-22:58*/
public class CMBFee extends CashFee {@Overridepublic String orderNo() {return "CMB"+ UUID.randomUUID();}@Overridepublic float price() {return 5.0f;}
}

农业银行

/*** 类描述** @author: 12405* @date: 2020/3/25-23:01*/
public class ABCFee extends CashFee {@Overridepublic String orderNo() {return "ABC"+ UUID.randomUUID();}@Overridepublic float price() {return 2.0f;}
}

Visa

import java.util.UUID;/*** 类描述** @author: 12405* @date: 2020/3/25-23:02*/
public class VisaFee extends CashFee {@Overridepublic String orderNo() {return "V"+ UUID.randomUUID();}@Overridepublic float price() {return 10.0f;}
}

7.FeeConfig类(用于构建计费相关信息)

import cn.yzstu.bulidermodule.interf.FeeInterf;import java.util.ArrayList;
import java.util.List;/*** 类描述** @author: 12405* @date: 2020/3/25-23:09*/
public class FeeConfig {private List<FeeInterf> feeList = new ArrayList<>();//往当前订单中加入可选的支付方式public void addFee(FeeInterf feeInterf){feeList.add(feeInterf);}//展示所有可选支付方式的相关信息public void showMyFee(){for (FeeInterf fee : feeList){System.out.println("OrderNo:"+fee.orderNo());System.out.println("FeeType:"+fee.feeType().feeType());System.out.println("Money:"+fee.price());}}
}

8.FeeBuilder类(提供给国内外的不同客户计费集)

import cn.yzstu.bulidermodule.impl.fee.*;/*** 类描述** @author: 12405* @date: 2020/3/25-23:23*/
public class FeeBuilder {//国内用户的支付方式public FeeConfig prepareChinaFee(){FeeConfig feeConfig = new FeeConfig();feeConfig.addFee(new ChinaMobileFee());feeConfig.addFee(new ChinaUnicomFee());feeConfig.addFee(new ABCFee());feeConfig.addFee(new CMBFee());return feeConfig;}//国外用户的支付方式public FeeConfig prepareIndoFee(){FeeConfig feeConfig = new FeeConfig();feeConfig.addFee(new IndoIsatFee());feeConfig.addFee(new IndoTselFee());feeConfig.addFee(new VisaFee());return feeConfig;}
}

9.FeeDemo测试(展示国内用户获取的计费集)

/*** 类描述** @author: 12405* @date: 2020/3/25-23:30*/
public class FeeDemo {public static void main(String[] args) {//获取国内计费集FeeConfig cFeeConfig = FeeBuilder.prepareChinaFee();//获取国外计费集FeeConfig iFeeConfig = FeeBuilder.prepareIndoFee();//展示国内用户能够获取到的计费集cFeeConfig.showMyFee();}
}
"C:\Program Files\Java\jdk1.8.0_171\bin\java.exe" "-javaagent:E:\tools\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=54341:E:\tools\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_171\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\rt.jar;E:\Workspaces\IdeaProjects\DemoTest\out\production\DemoTest" cn.yzstu.bulidermodule.FeeDemo
OrderNo:MOBL3a989c63-ce7f-4210-8193-adcab306929f
FeeType:SMS
Money:10.0
OrderNo:UNCd3504a9d-62a5-4fde-91a1-49e1d1df2b23
FeeType:SMS
Money:20.0
OrderNo:ABC33369090-2639-4653-82fa-f76fb397fa24
FeeType:Cash
Money:2.0
OrderNo:CMB845f2043-e297-49fd-b397-a061be5adf64
FeeType:Cash
Money:5.0Process finished with exit code 0

10.组件变动

上面我们已经用Builder成功获取到了我们想要的国内用户的计费方式集,其中FeeType是组件中不常改动的地方,而计费私有的属性则是我们经常改动的地方,比如我们现在想改动中国移动的计费点,直接在ChinaMobileFee中改动价格即可。

import java.util.UUID;/*** 类描述** @author: 12405* @date: 2020/3/25-22:49*/
public class ChinaMobileFee extends SMSFee {@Overridepublic String orderNo() {return "MOBL"+ UUID.randomUUID();}@Overridepublic float price() {return 20.0f;//改动价格}
}
"C:\Program Files\Java\jdk1.8.0_171\bin\java.exe" "-javaagent:E:\tools\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=54431:E:\tools\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_171\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\rt.jar;E:\Workspaces\IdeaProjects\DemoTest\out\production\DemoTest" cn.yzstu.bulidermodule.FeeDemo
OrderNo:MOBLd3140a28-55a3-4cb4-8de8-ce32043a3833
FeeType:SMS
Money:20.0
OrderNo:UNCb562defd-287b-4957-9a2c-e12a782a616b
FeeType:SMS
Money:20.0
OrderNo:ABCc6b54887-f18a-4e8a-b060-7a3fe6015a07
FeeType:Cash
Money:2.0
OrderNo:CMB21663c63-9a66-4b99-9ade-d5d9659975d3
FeeType:Cash
Money:5.0Process finished with exit code 0

五、总结

该模式的主要优点如下:

  1. 各个具体的建造者相互独立,有利于系统的扩展。
  2. 客户端不必知道产品内部组成的细节,便于控制细节风险。

其缺点如下:

  1. 产品的组成部分必须相同,这限制了其使用范围。

  2. 如果产品的内部变化复杂,该模式会增加很多的建造者类。

建造者(Builder)模式和工厂模式的关注点不同:建造者模式注重零部件的组装过程,而工厂方法模式更注重零部件的创建过程,但两者可以结合使用。

设计模式详解(四)--------建造者模式相关推荐

  1. Android设计模式详解之建造者模式

    前言 Builder模式是一种创建型设计模式. 定义:将一个复杂对象的创建与它的表示分离,使得同样的构造过程可以创建不同的表示. 使用场景: 相同的方法,不同的执行顺序,产生不同的事件结果时: 多个部 ...

  2. 设计模式详解:建造者模式

    今天来看一下创建新模式中的第五种模式:建造者模式.仍然是先看两张图,复习模式类型,加深记忆. 定义: 建造者模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. Build ...

  3. C++设计模式详解之外观模式解析

    C++ 外观模式 外观模式定义 外观模式提供了一个统一的接口,用来访问子系统中的一群接口,外观定义了一个高层接口,让子系统更容易使用. 个人理解:外观模式,实际就是添加一层封装 比较简单 外观模式实例 ...

  4. C++设计模式详解之模板模式解析

    C++ 模板方法模式解析 模板方法模式定义 模板方法定义了一个算法的步骤,并允许子类为一个或多个步骤提供实现 模板方法模式实例 以考试为例,考数学和考语文的过程几乎都是一样的,就是准备考试,背书,写试 ...

  5. C++设计模式详解之命令模式解析

    C++ 命令模式定义 命令模式将请求封装成对象,以便使用不同的请求,队列或者日志来参数化其他对象. 个人理解: 命令模式,其实实质上就是去耦合的操作,让各个部分尽可能的关联性降低,以便修改或增加某些功 ...

  6. C++设计模式详解之工厂模式解析

    C++ 工厂方法模式解析 工厂方法模式原则 让子类决定该创建的对象是什么,来达到将对象创建的过程.封装了对象创建的过程.实现了封装的目的.主要就是创建者类和产品类,让创建者自动绑定产品. 工厂方法模式 ...

  7. Android设计模式详解之解释器模式

    前言 解释器模式是一种使用较少的行为型模式: 提供了一种解释语言的语法或表达式的方式,通过该接口解释一个特定的上下文. 定义:给定一个语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示 ...

  8. Android设计模式详解之备忘录模式

    前言 备忘录模式是一种行为模式,该模式用于保存对象当前状态,并且在之后可以再次恢复到此状态: 定义:在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样,以后就可以将该对象恢 ...

  9. 《设计模式详解》创建型模式 - 建造者模式

    建造者模式 4.4 建造者模式 4.4.1 概述 4.4.2 结构 4.4.3 实例 4.4.4 优缺点 4.4.5 使用场景 4.4.6 扩展 - 构建对象 重构前 重构后 4.5 创建型模式对比 ...

  10. 设计模式(五)——建造者模式详解

    设计模式(五)--建造者模式详解 概述 结构 代码案例 优缺点 使用场景 模式扩展 创建者模式对比 工厂方法模式和建造者模式 抽象工厂模式和建造者模式 概述 建造者模式就是说将一个复杂对象的构建和表示 ...

最新文章

  1. 腾讯的人工智能大战已然打响!
  2. pandas DataFrame 索引(二)
  3. matlab的开方算法_正确的「记事本」打开方式:能渲染3D图像,还能玩贪吃蛇
  4. 构建了我的第一个React Native应用程序之后,我现在确信这是未来。
  5. mysql in 索引_mysql-IN子句不使用索引
  6. cocos2d-x之物理引擎初试
  7. pwershell custom objects
  8. linux dhcp服务器配置及小实验
  9. 直接插入排序和冒泡排序有什么区别 直接插入排序和冒泡排序有哪些不同
  10. pyaudio音频录制
  11. python3.8安装cartopy使用报错:DLL load failed while importing trace
  12. 多益网络产品专员面经分享
  13. 如何使用C++做个简单推箱子游戏
  14. npm/package.json/package-lock.json文件
  15. BAT齐聚阿里安全-ASRC生态大会:呼吁联合共建网络安全白色产业链
  16. Vue 项目如何进行 SEO 优化
  17. 通过JS代码动态生成HTML表格(Table),Input框,Button按钮.并且通过Input框的值进行查询动态生成数据填写在指定的表格里
  18. python查看excel编码格式_[Python]实现处理读写xlsx xls excel文件格式(含中文处理方法)...
  19. ROS2入门教程—理解话题(Topic)
  20. IP地址 归属地查询

热门文章

  1. Vite(三)部署静态站点(wordpress与hugo与Vercel、CI/CD、Travis CI、GitLab CI)、环境变量与模式、服务端渲染(SSR)
  2. STM32MP157驱动开发——RGB转HDMI
  3. 计算机系统在线安装,超详细的电脑装系统教程,手把手教你免费安装,再也不求人...
  4. 量子计算或可解救全球芯片危机
  5. KEPServerEX与Modbus设备通讯TCP和RTU
  6. 简述UIAlertView的属性和用法
  7. 联通信号手机测试软件,4G/Wi-Fi信号最好的手机竟是它:联通受伤
  8. 如何判断一个数是三的倍数,七的倍数,还是三和七的倍数,还是既不是三的倍数也不是七的倍数(vs版本)
  9. 只需1分钟,快速在无人机航测成果数据上提取“高程点”
  10. PHP摘桃子,幼儿园中班健康活动《摘桃子》