设计模式--Builder生成器模式
如果文章中哪里有问题,希望各位大哥大姐指出,小弟十分感激。
正文
什么是生成器模式?
生成器模式就是把生产对象的过程进一步抽取、细化、独立。以往我们生产对象,可能就是在一个小作坊里面从头做到尾。现在用了生成器模式,就等于把这些生产步骤细化分割了,进行了分散操作,一道工序完了就下一道工序,换一道工序就换个地方。举个例子,就像建房子,房子需要地基、主体、大门、房间、花园、地下室…….。按照以前的写法,就等于你雇了一个施工队,然后将整个房子的建造都交给他们,而且你还要把全部要求给他们说明白,不然他们要么全给你造了,要么全没造。用了生成器模式后,我们初始先生成最基础、最不可缺少的内容:地基和房子主体。并且将大门、房间、花园、地下室…….这些附加的东西都分别外包给不同的施工队(方法),你想加什么东西,就雇佣什么施工队(调方法),并告诉他们你要弄成什么样子。最后你在来个验收(生成最后的对象),那就行了。
为什么要用生成器模式?
像前面说的,用生成器将对象的生成过程细分成不同部分,然后我们就可以更准确的去控制这个对象的生成。生成器模式很适合那个生成过程很复杂,且对象内部结构复杂,多变的类。例如前面提及的房子类,他的内部结构有很多,每个内部结构(属性)又有不同形式(值),就很适合这种模式去生成。再例如汽车,内部有车身、引擎、轮胎、座椅等等,每种又有不同的厂家、型号,更是复杂多变。
怎样使用生成器模式?
首先我们需要一些最基本的东西:
1:我们要生产的最终产品对象,如House。
2:我们要有组成最终产品的各个部件,如Building、Door、Basement、Room、Garden。
3:有一个建筑造公司,这个建造公司要有不同的施工队,如Builder
4:(非必须)一个销售人员,直接给你推销最终产品,怎么造房子由销售人员去联系建筑公司。如Salesperson


代码很长,建议先跳过main方法看其他的,最后才看main方法。
/**
* 生成器模式
* */
public class BuilderHouse {
public static void main(String[] args) {
/** 我有1百万 */
double myMoney = 1000000;
/** 为了结婚去买套婚房 */
House myHouse = null;
/** 召唤一个售楼员 */
Salesperson salesperson = new Salesperson(); if(myMoney > 5000000) {
/** 售楼员觉得我可能有5百万,打算我推荐这个别墅 */
House bieShu = salesperson.bieShu();
myHouse = bieShu;
}else {
/** 可实际上我只是个穷鬼,所以售楼员推了这套80万的商品房 */
House shangPinLou = salesperson.shangPinLou();
/** 好了,这套在预算内,剁手了 */
myHouse = shangPinLou;
}
System.err.println(myHouse == null?"没房子找不到老婆":"有房子了,虽然小点,但起码老婆不嫌弃,美滋滋结婚了");
System.err.println(myHouse == null?"":myHouse);
}
} /**
* 房子--最终产品
* */
class House{
Building building; // 建筑主体
Door door; // 大门
List<Room> rooms; // 房间
Garden garden; // 花园
Basement basement; // 地下室
String description; // 房子简述
public House(Building building, Door door, List<Room> rooms, Garden garden, Basement basement,String description) {
this.building = building;
this.door = door;
this.rooms = rooms;
this.garden = garden;
this.basement = basement;
this.description = description;
}
public House() {}
@Override
public String toString() {
return "House [building=" + building + ", door=" + door + ", rooms=" + rooms + ", garden=" + garden
+ ", basement=" + basement + ", description=" + description + "]";
}
}
/**
* 建筑--也就是房子主体--中间产品
* */
class Building{
double area; // 面积
int floor; // 楼层
String description; // 大门描述
public Building(double area, int floor, String description) {
this.area = area;
this.floor = floor;
this.description = description;
}
public Building() { }
@Override
public String toString() {
return "Building [area=" + area + ", floor=" + floor + ", description=" + description + "]";
}
}
/**
* 大门--中间产品
* */
class Door{
double width; // 宽
double hight; // 高
String description; // 大门描述
public Door(double width, double hight, String description) {
this.width = width;
this.hight = hight;
this.description = description;
}
public Door() { }
@Override
public String toString() {
return "Door [width=" + width + ", hight=" + hight + ", description=" + description + "]";
}
}
/**
* 房间--中间产品
* */
class Room{
double area; // 面积
String description; // 房间描述
int windowNum; // 窗户个数
public Room(double area, String description, int windowNum) {
this.area = area;
this.description = description;
this.windowNum = windowNum;
}
public Room() { }
@Override
public String toString() {
return "Room [area=" + area + ", description=" + description + ", windowNum=" + windowNum + "]";
}
}
/**
* 花园--中间产品
* */
class Garden{
double area; // 面积
String description; // 花园样子
boolean hasSwimmingPool;// 是否要泳池
public Garden() {}
public Garden(double area, String description, boolean hasSwimmingPool) {
this.area = area;
this.description = description;
this.hasSwimmingPool = hasSwimmingPool;
}
@Override
public String toString() {
return "Garden [area=" + area + ", description=" + description + ", hasSwimmingPool=" + hasSwimmingPool + "]";
}
}
/**
* 地下室--中间产品
* */
class Basement{
double area; // 面积
double hight; // 地下室高
String description; // 地下室样子
public Basement() { }
public Basement(double area, double hight, String description) {
this.area = area;
this.hight = hight;
this.description = description;
}
@Override
public String toString() {
return "Basement [area=" + area + ", hight=" + hight + ", description=" + description + "]";
}
}
/**
* 建造者,也就是建筑公司
* */
class HouseBuilder{
House house; // 房子
public HouseBuilder() {
this.house = new House();
}
/**
* 建筑主体施工队,构建建筑主体
* */
public HouseBuilder buildBuilding(double area,int floor,String description) {
Building building = new Building();
building.area = area;
building.floor = floor;
building.description = description;
this.house.building = building;
return this;
}
/**
* 大门施工队,构建房子的大门
* */
public HouseBuilder buildDoor(double width,double hight,String description) {
Door door = new Door();
door.width = width;
door.hight = hight;
door.description = description;
this.house.door = door;
return this;
}
/**
* 房间施工队,构建房子的房间
* */
public HouseBuilder buildRooms(double area,int windowNum,String description,int roomNum) {
Room room = null;
List<Room> rooms = new ArrayList<Room>(roomNum);
for (int i = 0; i < roomNum; i++) {
room = new Room();
room.area = area;
room.windowNum = windowNum;
room.description = description;
rooms.add(room);
}
this.house.rooms = rooms;
return this;
}
/**
* 花园施工队,构建房子的花园
* */
public HouseBuilder buildGarden(double area,boolean hasSwimmingPool,String description) {
Garden garden = new Garden();
garden.area = area;
garden.hasSwimmingPool = hasSwimmingPool;
garden.description = description;
this.house.garden = garden;
return this;
}
/**
* 花园施工队,构建房子的花园
* */
public HouseBuilder buildBasement(double area,double hight,String description) {
Basement basement = new Basement();
basement.area = area;
basement.hight = hight;
basement.description = description;
this.house.basement = basement;
return this;
}
/**
* 验收,也就是生成最终产品
* */
public House createHouse() {
return this.house;
}
}
/**
* 销售员,可以可有可无,如果不用的话,那他的工作就是交给业务程序来做
* */
class Salesperson {
/**
* 原谅我的拼音,商品房
* */
public House shangPinLou() {
HouseBuilder houseBuilder = new HouseBuilder();
houseBuilder.buildBuilding(120, 1, "120平方的一层商品房,毛坯房")
.buildDoor(1.5, 2, "豪华大铁门一扇")
.buildRooms(20, 2, "3个20平方两窗户的大房间", 3);
House house = houseBuilder.createHouse();
house.description = "120平方的一层商品房,三室两厅,毛坯房";
return house;
}
/**
* 原谅我的拼音,商品房
* */
public House bieShu() {
HouseBuilder houseBuilder = new HouseBuilder();
houseBuilder.buildBuilding(400, 4, "400平方的5层大别墅,精装修")
.buildDoor(5, 2, "别墅专用铁栅栏门")
.buildRooms(60, 3, "5个60平带阳台豪华大房间", 5)
.buildBasement(100, 3, "100平3米高地下室")
.buildGarden(80, true, "80平带泳池大花园");
House house = houseBuilder.createHouse();
house.description = "400平方的5层大别墅,5室3厅,100平地下室,80平带泳池大花园,精装修,拎包入住";
return house;
}
}
设计模式--Builder生成器模式的更多相关文章
- Java设计模式-Builder生成器模式
概念: 生成器模式也称之为建造者模式.生成器模式的意图在于将一个复杂的构建与其表示相分离,构建与产品分离. UML: Ibuild接口清晰地反映了创建产品Product的流程. 生成器模式涉及4个关键 ...
- 每天一个设计模式-7 生成器模式(Builder)
每天一个设计模式-7 生成器模式(Builder) 一.实际问题 在讨论工厂方法模式的时候,提到了一个导出数据的应用框架,但是并没有涉及到导出数据的具体实现,这次通过生成器模式来简单实现导出成文本,X ...
- 设计模式03: Builder 生成器模式(创建型模式)
Builder生成器模式(创建型模式) Builder模式缘起假设创建游戏中的一个房屋House设施,该房屋的构建由几个部分组成,且各个部分富于变化.如果使用最直观的设计方法,每个房屋部分的变化,都将 ...
- 【设计模式】- 生成器模式(Builder)
生成器模式 建造者模式.Builder 生成器模式 也叫建造者模式,可以理解成可以分步骤创建一个复杂的对象.在该模式中允许你使用相同的创建代码生成不同类型和形式的对象. 生成器的结构模式 生成器(Bu ...
- 设计模式(二): BUILDER生成器模式 -- 创建型模式
1.定义 将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式. 2.适用场景 1. 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式 ...
- 面向对象设计模式_生成器模式详解(Builder Pattern)
首先提出一个很容易想到应用场景: 手机的生产过程:手机有非常多的子件(部件),成千上万,不同品牌的手机的生产过程都是复杂而有所区别的,相同品牌的手机在设计上也因客户需求多样化,大到型号,小到颜色,是否 ...
- 设计模式十: 生成器模式(Builder Pattern)
简介 生成器模式属于创建型模式的一种, 又叫建造者模式. 生成器模式涉及4个关键角色:产品(Product),抽象生成器(builder),具体生成器(ConcreteBuilder),指挥者(Dir ...
- 面向对象设计模式_生成器模式解读(Builder Pattern)
首先提出一个很容易想到应用场景: 手机的生产过程:手机有非常多的子件(部件),成千上万,不同品牌的手机的生产过程都是复杂而有所区别的,相同品牌的手机在设计上也因客户需求多样化,大到型号,小到颜色,是否 ...
- Java设计模式:生成器模式
问题的提出: 有些类很容易创建对象,直接调用其构造方法,例如Student student = new Student("1001","zhang",21); ...
随机推荐
- ES6-变量let和常量const
1.以往js变量 var 1.可以重复声明 2.无法限制修改(指不能声明常量) 3.没有块级作用域(指{}这样的) 2.现在ES6变量 let 不能重复声明-变量,可以修改,块级作用域 const 不 ...
- webstorm 单词快捷翻译设置
1.打开webstorm中的设置,选择plugins,搜索 translations 安装,安装完成重启webstorm 2.设置快捷键翻译,打开webstorm设置,选择keymap,搜索trans ...
- 前端HTML学习 table标签 知识点与使用
表格基本结构 <table> <tr> <td>单元格</td> </tr> </table> < tr >表示 行 ...
- webpack+vue2.0项目 (二)热加载,vue-router
目录创建好之后,命令行输入 npm run dev 因为在配置文件config/index.js里: dev: { env: require('./dev.env'), port: 8080, aut ...
- Java实现 LeetCode 805 数组的均值分割 (DFS+分析题)
805. 数组的均值分割 给定的整数数组 A ,我们要将 A数组 中的每个元素移动到 B数组 或者 C数组中.(B数组和C数组在开始的时候都为空) 返回true ,当且仅当在我们的完成这样的移动后,可 ...
- Java实现 LeetCode 38 外观数列
38. 外观数列 「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述.前五项如下: 1 11 21 1211 111221 1 被读作 "one 1" ...
- 用斗地主的实例学会使用java Collections工具类
目录 一.背景 二.概念 1.定义 2.方法 2.1.排序方法 2.2.查找/替换方法 三.斗地主实例 3.1.代码结构 3.2.常量定义 3.3.单只牌类 3.4.玩家类 3.5.主程序 四.深入理 ...
- Centos网络配置文件详解
配置文件位置: 根目录下面的etc下面的sysconfig下面的network-scripts下面的网卡名称配置文件. /etc/sysconfig/network-scripts/网卡名称 如图:我 ...
- Dubbo+Zookeeper集群案例
一.开源分布式服务框架 1.Dubbo是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以Spring框架无缝集成. Dubbo是一款高性 ...
- 构建自己的jar包上传至Mvaen中央仓库和版本更新
构建自己的jar包上传至Mvaen中央仓库和版本更新 一直羡慕别人制造轮子,开源项目,供别人使用:我也想这样,可以自己才疏学浅,本次就将自己写小工具上传到Maven的中央仓库. 一步一步详细教程演示如 ...