设计模式--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); ...
随机推荐
- 第四篇-用Flutter手撸一个抖音国内版,看看有多炫
前言 这次对布局进行优化,主要包含了首页tabview pageview 以及添加几个按钮的操作过程.主要使用到stack层叠布局,tabpview和pageview,tabview两个页面,一个关注 ...
- Rocket - diplomacy - AddressAdjuster分析
https://mp.weixin.qq.com/s/UYVSO3XFJmhe5bUD_XbMLg 先介绍如何使用AddressAdjuster,然后分析UI参数的生成及使用. 1. ...
- ActiveMQ 笔记(八)高级特性和大厂常考重点
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 1.可用性保证 引入消息队列之后该如何保证其高可用性? 持久化.事务.签收. 以及带复制的 Leavel ...
- http1.0 、http1.1和http2.0的区别
一.HTTP1.0 HTTP 1.1主要区别 1.1 长链接 HTTP 1.0需要使用keep-alive参数来告知服务器端要建立一个长连接,而HTTP1.1默认支 ...
- ProxySQL简介原理及读写分离应用
MySQL-ProxySQL中间件简介 同类型产品 MySQL Route:是现在MySQL官方Oracle公司发布出来的一个中间件. Atlas:是由奇虎360公发的基于MySQL协议的数据库中间件 ...
- JNI_day02
二级指针 指向指针变量的指针,保存指针的地址 结构体 struct Student //struct Stdent 学生结构体类型 { int id;//成员 char name[20]; int a ...
- Jupyter的搭建
在家实在无聊,伏案沉思良久,忽然灵机一动,何不写写Python?然而电脑上的软件早已人是物非,Pycharm已然不复存在.但是又不想装软件找激活码,于是,只好建个Jupyter先凑合一下. 1. 安装 ...
- python模拟网站登陆-滑动验证码
普通滑动验证 以http://admin.emaotai.cn/login.aspx为例这类验证码只需要我们将滑块拖动指定位置,处理起来比较简单.拖动之前需要先将滚动条滚动到指定元素位置. impor ...
- 关于微信小程序的文档-手撸
学习小程序的人如果有vue基础的话应该有很好的帮助作用.没有也关系,反正很简单. 首先理解一个完整的小程序app都有什么页面: pages页面放置所有的页面文件. 一个完整的小程序页面文件包括: in ...
- Mysql 视图用途、使用场景、性能问题及使用注意事项
原文:https://blog.csdn.net/chuangxin/article/details/84574557 <SQLite权威指南>中作者是这么定义视图的:视图即是虚拟表,也称 ...