JAVA设计模式什么鬼(建造者)——作者:凸凹里歐
建造者,用于对复杂对象的构造、初始化,与工厂模式不同的是,建造者的目的在于把复杂构造过程从不同对象展现中抽离出来,使得同样的构造工序可以展现出不同的产品对象。
打个比方,我们知道角色扮演类游戏中玩家可以选择不同的职业,各职业攻击力、防御力等等属性设定是不同的,比如战士的力量和体力强,法师的灵力强而体力弱,以及穿戴各种装备引起的属性附加。
假设我们用同一个类来描述这些角色,那么应该怎样新建人物并配备初始武器?交给客户端去完成,把法师配成战士的力量并给脑袋上装备一把屠龙刀吗?诚然,客户端根本不知道怎样去配置(更没有必要知道),游戏人设应该交给专业的团队(建造者模式)去完成,否则会造成不可预知的混乱角色,如同怪物一般的bug存在。
好了,让我们来规划一下专业的建造团队。既然是建造者,那就应该造点建造物了,我们就以盖房子举例。
房子本身有很多个组成部分,各组件息息相关缺一不可,否则房倒屋塌。而其构造过程也是相当复杂的,但大家不必担心,为响应我们简约直观的一贯宗旨,这里只将其简化拆分成地基、墙体、屋顶三部分,首先来看建筑物类。
1 public class Building {// 建筑物23 // 用来模拟房子组件的堆叠4 private List<String> buildingComponents = new ArrayList<>();56 public void setBasement(String basement) {// 地基7 this.buildingComponents.add(basement);8 }9
10 public void setWall(String wall) {// 墙体
11 this.buildingComponents.add(wall);
12 }
13
14 public void setRoof(String roof) {// 房顶
15 this.buildingComponents.add(roof);
16 }
17
18 @Override
19 public String toString() {
20 String buildingStr = "";
21 for (int i = buildingComponents.size() - 1; i >= 0; i--) {
22 buildingStr += buildingComponents.get(i);
23 }
24 return buildingStr;
25 }
26
27 }
为了模拟建筑物通用类中各组件的建造顺序,我们在第4行以List来模拟三个组件的堆叠,之后是它们对应的三个建造方法,最后于第19行的toString方法自下而上的打印出最终完成的房子。看起来是不难,但怎样从这个类直接构造出一个房子呢?怎样去设置这些字符串的组件属性呢?此时客户端一头雾水,还是找个专业施工方吧,先定义个施工方接口。
1 public interface Builder {//施工方接口23 public void buildBasement();45 public void buildWall();67 public void buildRoof();89 public Building getBuilding();
10
11 }
既然是施工方的接口,那一定有实现类了,先来写一个高端别墅施工队。
1 public class HouseBuilder implements Builder {//别墅施工方23 private Building house;45 public HouseBuilder() {6 house = new Building();7 }89 @Override
10 public void buildBasement() {
11 System.out.println("挖地基,部署管道、线缆,水泥加固,搭建围墙、花园。");
12 house.setBasement("╬╬╬╬╬╬╬╬\n");
13 }
14
15 @Override
16 public void buildWall() {
17 System.out.println("搭建木质框架,石膏板封墙并粉饰内外墙。");
18 house.setWall("|田|田 田|\n");
19 }
20
21 @Override
22 public void buildRoof() {
23 System.out.println("建造木质屋顶、阁楼,安装烟囱,做好防水。");
24 house.setRoof("╱◥███◣\n");
25 }
26
27 @Override
28 public Building getBuilding() {
29 return house;
30 }
31
32 }
嗯,这个施工方看起来是有施工资质的,不管是地基、墙体还是屋顶都讲得(第11行等)头头是道,虽然我们不懂,但建造工艺(第12行等)看起来也都是非常有考究,总之是极其专业的施工方并统统实现了每个组件的建造方法,下来我们同样地再请一个公寓楼的施工队。
1 public class ApartmentBuilder implements Builder {// 高层公寓楼施工方23 private Building apartment;45 public ApartmentBuilder() {6 apartment = new Building();7 }89 @Override
10 public void buildBasement() {
11 System.out.println("深挖地基,修建地下车库,部署管道、线缆、风道。");
12 apartment.setBasement("╚═════════╝\n");
13 }
14
15 @Override
16 public void buildWall() {
17 System.out.println("搭建多层建筑框架,建造电梯井,钢筋混凝土浇灌。");
18 for (int i = 0; i < 8; i++) {// 此处假设固定8层
19 apartment.setWall("║ □ □ □ □ ║\n");
20 }
21 }
22
23 @Override
24 public void buildRoof() {
25 System.out.println("封顶,部署通风井,做防水层,保温层。");
26 apartment.setRoof("╔═════════╗\n");
27 }
28
29 @Override
30 public Building getBuilding() {
31 return apartment;
32 }
33
34 }
大同小异,公寓楼施工方也是一样的专业,只不过建造工艺好像有些不同,尤其是第16行的建造墙体方法,好像是循环8次造了8层楼的样子,这一定是八层公寓小高层了。到这里,我们好像还是不能交给客户端去亲自调用这三个组件的建造方法,造房子可不是开玩笑的,我们还是得找一个有资质的工程总监去控制整个建造工序流程。
1 public class Director {//工程总监23 private Builder builder;45 public Director(Builder builder) {6 this.builder = builder;7 }89 public void setBuilder(Builder builder) {
10 this.builder = builder;
11 }
12
13 public Building direct() {
14 System.out.println("=====工程项目启动=====");
15 // 第一步,打好地基;
16 builder.buildBasement();
17 // 第二步,建造框架、墙体;
18 builder.buildWall();
19 // 第三步,封顶;
20 builder.buildRoof();
21 System.out.println("=====工程项目竣工=====");
22 return builder.getBuilding();
23 }
24
25 }
我们可以看到,工程总监在宏观上操控着整个施工队的建造流程,在第13行的指导方法中以自下而上的顺序建造房屋,他并不在乎是哪个施工队来造房子,但施工步骤是由他来控制的。是时候满足客户的住房刚需了,组建团队,运行程序。
1 public class Client {23 public static void main(String[] args) {4 //招工,建别墅。5 Builder builder = new HouseBuilder();6 //交给工程总监7 Director director = new Director(builder);8 System.out.println(director.direct());9 //替换施工方,建公寓。
10 director.setBuilder(new ApartmentBuilder());
11 System.out.println(director.direct());
12 }
13
14 }
可以看到客户端先找了个别墅施工队(第5行),并且安排给总监(第7行),于是造出了别墅,接着又替换了另一个公寓楼施工队(第10行),最终顺利地建了一栋八层公寓,结果如下。
项目终于竣工了,对于复杂对象的构建,专业的建造团队显然是不可或缺的,尤其是产品内部组件间有某种关联性,构建的顺序性,所以我们把制造工序抽离出来交给了工程总监(Director),而产品各种制造工艺则被多态化交给不同的施工方(Builder)去各显神通,最终达成以相同的构造过程生产不同产品的展现的目的,工序不可乱,工艺不可缺。
JAVA设计模式什么鬼(建造者)——作者:凸凹里歐相关推荐
- JAVA设计模式什么鬼(备忘录)——作者:凸凹里歐
备忘录,备份曾经发生过的历史记录,以防忘记,之后便可以轻松回溯过往.想必我们曾经都干过很多蠢事导致糟糕的结果,当后悔莫及的时候已经是覆水难收了,只可惜这世界上没有后悔药,事后我们能做的只能去弥补过失, ...
- JAVA设计模式什么鬼(策略)——作者:凸凹里歐
策略,Strategy,古时也称"计",为了达成某个目标的方案,目标不同,方案也随之更改.例如特工执行任务时总要准备好几套方案以应对突如其来的变化,A计划实施过程中情况突变导致预案 ...
- JAVA设计模式什么鬼(状态)——作者:凸凹里歐
状态State,指某事物所处的状况或形态,比如水的三态,零下会变成固态冰,常温会是液态水,100℃会蒸发成气态的水蒸气. 在这个地球生态系统中,水的总量并不会增加,也不会减少,只是随着温度的变化其分子 ...
- JAVA设计模式什么鬼(代理)——作者:凸凹里歐
代理,代表打理,以他人的名义代表委托人打理其本职工作之外或不所能及的事务,达成合作关系并更高效地促成事务完成的目的.例如明星经纪人,他们并没有像明星一样会唱歌.跳舞或演戏,而是替明星打理一些无暇顾及的 ...
- JAVA设计模式什么鬼(初探)——作者:凸凹里歐
有物混成,先天地生.寂兮寥兮,独立而不改,周行而不殆,可以为天地母.吾不知其名,字之曰道,强为之名曰大.大曰逝,逝曰远,远曰反. 道是什么?道可道,非常道.道不明,说不尽的才算是道,它是自然法则的终极 ...
- JAVA设计模式什么鬼(适配器)——作者:凸凹里歐
我们这个世界,充满着千奇百怪的对象,更有趣的是对象与对象间是存在着互动,沟通,这样世界才变得美妙.那到底是怎样互动呢?靠什么才能互动呢?是的,接口.比如你和朋友一起喝茶聊天,我们暂且不管声带,耳膜这些 ...
- JAVA设计模式什么鬼(装饰)——作者:凸凹里歐
装饰,在某物件基础上加以修饰,装点,使得原本的朴素变得华丽,达到化腐朽为神奇的效果.比如我们从开发商买来的毛坯房,必然要进行室内装潢这么一项工程,什么简约风啊,北欧风啊,地中海,美式中式等等,当然萝卜 ...
- JAVA设计模式什么鬼(模板方法)——作者:凸凹里歐
面向对象,是对事物属性与行为的封装,方法,指的就是行为.模板方法,显而易见是说某个方法充当了模板的作用,其充分利用了抽象类虚实结合的特性,虚部抽象预留,实部固定延续,以达到将某种固有行为延续至子类的目 ...
- JAVA设计模式什么鬼(门面)——作者:凸凹里歐
开门见山,门,建筑物的入口,面,脸也.门面(Facade),通常指店铺的门头外表部分,当然一定要临街才是好的商铺,在人流量大的地方营造更好的视觉冲击,这样会有更多等等机会暴露给潜在顾客,否则只能是靠& ...
最新文章
- 达达O2O后台架构演进实践:从0到4000高并发请求背后的努力!
- 清华袁洋:智能医疗不是让AI替代医生,而是……
- LiveGBS无插件播放页面的集成----单独的播放器样式
- PAT甲级1109 Group Photo:[C++题解]双指针
- node.js 下载安装及gitbook环境安装、搭建
- springsecurity sessionregistry session共享_要学就学透彻!Spring Security 中 CSRF 防御源码解析...
- NMS(非极大值抑制)算法详解与示例
- php环行队列实现,java数组实现队列及环形队列实现过程解析
- 软件定义网络文章列表
- android UI 标签
- vscode 5500 but failed to open in Browser Preview. Got Browser Preview extension installed?
- 零基础学启发式算法(4)-模拟退火 (Simulated Annealing)
- 计算机软件安装流程,计算机软件系统快速安装流程简介
- 电脑上有什么类似全能扫描王的软件?这4款扫描app1分钟帮你搞定几十张图片
- Arduino学习笔记—— 猜数字游戏
- Chrome浏览器的复用
- 经典搜索算法之B树与B+树
- 免费顶级域名.OVH注册申请全过程附成功注册小技
- springboot 中如何使用 ingest-attachment
- c语言输出国旗图形,大家来看看国旗杂画