重学 Java 设计模式:实战建造者模式
2021-01-07 13:30
标签:传统行业 部署 成功 源码下载 app scene 互联网 tip 测试结果 沉淀、分享、成长,让自己和他人都能有所收获!?? 无论承接什么样的需求,是不是身边总有那么几个人代码写的烂,但是却时常有测试小姐姐过来聊天(求改bug)、有产品小伙伴送吃的(求写需求)、有业务小妹妹陪着改代码(求上线),直至领导都认为他的工作很重要,而在旁边的你只能蹭点吃的。 这样的小伙伴,可能把代码写的很直接, 第一次完成产品需求实在是很快,但互联网的代码不比传统企业。在传统行业可能一套代码能用十年,但在互联网高速的迭代下你的工程,一年就要变动几十次。如果从一开始就想着只要完成功能就可以,那么随之而来的是后续的需求难以承接,每次看着成片成片的代码,实在不知如何下手。 一个项目的上线往往要经历 开发代码的过程不是 所以我们也需要一些设计模式的标准思想,去建设代码结构,提升全局把控能力。 建造者模式所完成的内容就是通过将多个简单对象通过一步步的组装构建出一个复杂对象的过程。 例如你玩王者荣耀的时的初始化界面;有三条路、有树木、有野怪、有守卫塔等等,甚至依赖于你的网络情况会控制清晰度。而当你换一个场景进行其他不同模式的选择时,同样会建设道路、树木、野怪等等,但是他们的摆放和大小都有不同。这里就可以用到建造者模式来初始化游戏元素。 而这样的根据相同的 这里我们模拟装修公司对于设计出一些套餐装修服务的场景。 很多装修公司都会给出自家的套餐服务,一般有;欧式豪华、轻奢田园、现代简约等等,而这些套餐的后面是不同的商品的组合。例如;一级&二级吊顶、多乐士涂料、圣象地板、马可波罗地砖等等,按照不同的套餐的价格选取不同的品牌组合,最终再按照装修面积给出一个整体的报价。 这里我们就模拟装修公司想推出一些套餐装修服务,按照不同的价格设定品牌选择组合,以达到使用建造者模式的过程。 在模拟工程中提供了装修中所需要的物料; 一级顶 二级顶 多乐士 立邦 德尔 圣象 东鹏 马可波罗 每一个章节中我们都会使用这样很直白的方式去把功能实现出来,在通过设计模式去优化完善。这样的代码结构也都是非常简单的,没有复杂的类关系结构,都是直来直去的代码。除了我们经常强调的这样的代码不能很好的扩展外,做一些例子demo工程还是可以的。 一个类几千行的代码你是否见过,嚯?那今天就让你见识一下有这样潜质的类! 接下来我们通过junit单元测试的方式验证接口服务,强调日常编写好单测可以更好的提高系统的健壮度。 编写测试类: 结果: 建造者模式主要解决的问题是在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的过程构成;由于需求的变化,这个复杂对象的各个部分经常面临着重大的变化,但是将它们组合在一起的过程却相对稳定。 这里我们会把构建的过程交给 建造者模型结构 工程中有三个核心类和一个测试类,核心类是建造者模式的具体实现。与 好,那么接下来会分别讲解几个类的具体实现。 编写测试类: 结果: 重学 Java 设计模式:实战建造者模式 标签:传统行业 部署 成功 源码下载 app scene 互联网 tip 测试结果 原文地址:https://www.cnblogs.com/xiaofuge/p/12970960.html
作者:小傅哥
博客:https://bugstack.cn - 原创系列专题文章
一、前言
乱码七糟 [luàn qī bā zāo],我时常怀疑这个成语是来形容程序猿的!
那你说,CRUD的代码还想让我怎么样?
ifelse
多用一点,满足于先临时支持一下,想着这也没什么的。而且这样的业务需求要的急又都是增删改查的内容,实在不想做设计。而如果有人提到说好好设计下,可能也会被反对不要过渡设计。贴膏药似的修修补补,一次比一次恐怖!
在研发流程规范下执行,才能写出好程序!
业务需求
、产品设计
、研发实现
、测试验证
、上线部署
到正式开量
,而这其中对研发非常重要的一换就是研发实现的过程,又可以包括为;架构选型
、功能设计
、设计评审
、代码实现
、代码评审
、单测覆盖率检查
、编写文档
、提交测试
。所以在一些流程规范下,其实很难让你随意开发代码。炫技
,就像盖房子如果不按照图纸来修建,回首就在山墙上搭一个厨房卫浴!可能在现实场景中这很荒唐,但在功能开发中却总有这样的代码。二、开发环境
bugstack虫洞栈
,回复源码下载
获取(打开获取的链接,找到序号18)
工程
描述
itstack-demo-design-3-00
场景模拟工程,模拟装修过程中的套餐选择(豪华、田园、简约)
itstack-demo-design-3-01
使用一坨代码实现业务需求,也是对ifelse的使用
itstack-demo-design-3-02
通过设计模式优化改造代码,产生对比性从而学习
三、建造者模式介绍
那么,哪里有这样的场景呢?
物料
,不同的组装所产生出的具体的内容,就是建造者模式的最终意图,也就是;将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。四、案例场景模拟
1. 场景模拟工程
itstack-demo-design-3-00
└── src
└── main
└── java
└── org.itstack.demo.design
├── ceilling
│ ├── LevelOneCeiling.java
│ └── LevelTwoCeiling.java
├── coat
│ ├── DuluxCoat.java
│ └── LiBangCoat.java
│ └── LevelTwoCeiling.java
├── floor
│ ├── DerFloor.java
│ └── ShengXiangFloor.java
├── tile
│ ├── DongPengTile.java
│ └── MarcoPoloTile.java
└── Matter.java
ceilling(吊顶)
、coat(涂料)
、floor(地板)
、tile(地砖)
,这么四项内容。(实际的装修物料要比这个多的多)2. 场景简述
2.1 物料接口
public interface Matter {
String scene(); // 场景;地板、地砖、涂料、吊顶
String brand(); // 品牌
String model(); // 型号
BigDecimal price(); // 价格
String desc(); // 描述
}
2.2 吊顶(ceiling)
public class LevelOneCeiling implements Matter {
public String scene() {
return "吊顶";
}
public String brand() {
return "装修公司自带";
}
public String model() {
return "一级顶";
}
public BigDecimal price() {
return new BigDecimal(260);
}
public String desc() {
return "造型只做低一级,只有一个层次的吊顶,一般离顶120-150mm";
}
}
public class LevelTwoCeiling implements Matter {
public String scene() {
return "吊顶";
}
public String brand() {
return "装修公司自带";
}
public String model() {
return "二级顶";
}
public BigDecimal price() {
return new BigDecimal(850);
}
public String desc() {
return "两个层次的吊顶,二级吊顶高度一般就往下吊20cm,要是层高很高,也可增加每级的厚度";
}
}
2.3 涂料(coat)
public class DuluxCoat implements Matter {
public String scene() {
return "涂料";
}
public String brand() {
return "多乐士(Dulux)";
}
public String model() {
return "第二代";
}
public BigDecimal price() {
return new BigDecimal(719);
}
public String desc() {
return "多乐士是阿克苏诺贝尔旗下的著名建筑装饰油漆品牌,产品畅销于全球100个国家,每年全球有5000万户家庭使用多乐士油漆。";
}
}
public class LiBangCoat implements Matter {
public String scene() {
return "涂料";
}
public String brand() {
return "立邦";
}
public String model() {
return "默认级别";
}
public BigDecimal price() {
return new BigDecimal(650);
}
public String desc() {
return "立邦始终以开发绿色产品、注重高科技、高品质为目标,以技术力量不断推进科研和开发,满足消费者需求。";
}
}
2.4 地板(floor)
public class DerFloor implements Matter {
public String scene() {
return "地板";
}
public String brand() {
return "德尔(Der)";
}
public String model() {
return "A+";
}
public BigDecimal price() {
return new BigDecimal(119);
}
public String desc() {
return "DER德尔集团是全球领先的专业木地板制造商,北京2008年奥运会家装和公装地板供应商";
}
}
public class ShengXiangFloor implements Matter {
public String scene() {
return "地板";
}
public String brand() {
return "圣象";
}
public String model() {
return "一级";
}
public BigDecimal price() {
return new BigDecimal(318);
}
public String desc() {
return "圣象地板是中国地板行业著名品牌。圣象地板拥有中国驰名商标、中国名牌、国家免检、中国环境标志认证等多项荣誉。";
}
}
2.5 地砖(tile)
public class DongPengTile implements Matter {
public String scene() {
return "地砖";
}
public String brand() {
return "东鹏瓷砖";
}
public String model() {
return "10001";
}
public BigDecimal price() {
return new BigDecimal(102);
}
public String desc() {
return "东鹏瓷砖以品质铸就品牌,科技推动品牌,口碑传播品牌为宗旨,2014年品牌价值132.35亿元,位列建陶行业榜首。";
}
}
public class MarcoPoloTile implements Matter {
public String scene() {
return "地砖";
}
public String brand() {
return "马可波罗(MARCO POLO)";
}
public String model() {
return "缺省";
}
public BigDecimal price() {
return new BigDecimal(140);
}
public String desc() {
return "“马可波罗”品牌诞生于1996年,作为国内最早品牌化的建陶品牌,以“文化陶瓷”占领市场,享有“仿古砖至尊”的美誉。";
}
}
装修配置单
,接下我们会通过案例去使用不同的物料组合出不同的套餐服务。五、用一坨坨代码实现
讲道理没有ifelse解决不了的逻辑,不行就在加一行!
1. 工程结构
itstack-demo-design-3-01
└── src
└── main
└── java
└── org.itstack.demo.design
└── DecorationPackageController.java
2. ifelse实现需求
public class DecorationPackageController {
public String getMatterList(BigDecimal area, Integer level) {
List
if
块里,都包含着不通的材料(吊顶,二级顶、涂料,立邦、地砖,马可波罗),最终生成装修清单和装修成本。3. 测试验证
@Test
public void test_DecorationPackageController(){
DecorationPackageController decoration = new DecorationPackageController();
// 豪华欧式
System.out.println(decoration.getMatterList(new BigDecimal("132.52"),1));
// 轻奢田园
System.out.println(decoration.getMatterList(new BigDecimal("98.25"),2));
// 现代简约
System.out.println(decoration.getMatterList(new BigDecimal("85.43"),3));
}
-------------------------------------------------------
装修清单
套餐等级:1
套餐价格:198064.39 元
房屋面积:132.52 平米
材料清单:
吊顶:装修公司自带、二级顶、平米价格:850 元。
涂料:多乐士(Dulux)、第二代、平米价格:719 元。
地板:圣象、一级、平米价格:318 元。
-------------------------------------------------------
装修清单
套餐等级:2
套餐价格:119865.00 元
房屋面积:98.25 平米
材料清单:
吊顶:装修公司自带、二级顶、平米价格:850 元。
涂料:立邦、默认级别、平米价格:650 元。
地砖:马可波罗(MARCO POLO)、缺省、平米价格:140 元。
-------------------------------------------------------
装修清单
套餐等级:3
套餐价格:90897.52 元
房屋面积:85.43 平米
材料清单:
吊顶:装修公司自带、一级顶、平米价格:260 元。
涂料:立邦、默认级别、平米价格:650 元。
地砖:东鹏瓷砖、10001、平米价格:102 元。
Process finished with exit code 0
ifelse
方式实现的代码,目前已经满足的我们的也许功能。但随着老板对业务的快速发展要求,会提供很多的套餐针对不同的户型。那么这段实现代码将迅速扩增到几千行,甚至在修修改改中,已经像膏药一样难以维护。六、建造者模式重构代码
接下来使用建造者模式来进行代码优化,也算是一次很小的重构。
创建者
类,而创建者通过使用我们的构建工具包
,去构建出不同的装修套餐
。1. 工程结构
itstack-demo-design-3-02
└── src
├── main
│ └── java
│ └── org.itstack.demo.design
│ ├── Builder.java
│ ├── DecorationPackageMenu.java
│ └── IMenu.java
└── test
└── java
└── org.itstack.demo.design.test
└── ApiTest.java
ifelse
实现方式相比,多出来了两个二外的类。具体功能如下;
Builder
,建造者类具体的各种组装由此类实现。DecorationPackageMenu
,是IMenu
接口的实现类,主要是承载建造过程中的填充器。相当于这是一套承载物料和创建者中间衔接的内容。2. 代码实现
2.1 定义装修包接口
public interface IMenu {
IMenu appendCeiling(Matter matter); // 吊顶
IMenu appendCoat(Matter matter); // 涂料
IMenu appendFloor(Matter matter); // 地板
IMenu appendTile(Matter matter); // 地砖
String getDetail(); // 明细
}
吊顶
、涂料
、地板
、地砖
,以及最终提供获取全部明细的方法。2.2 装修包实现
public class DecorationPackageMenu implements IMenu {
private List
this
,也就可以非常方便的用于连续填充各项物料。2.3 建造者方法
public class Builder {
public IMenu levelOne(Double area) {
return new DecorationPackageMenu(area, "豪华欧式")
.appendCeiling(new LevelTwoCeiling()) // 吊顶,二级顶
.appendCoat(new DuluxCoat()) // 涂料,多乐士
.appendFloor(new ShengXiangFloor()); // 地板,圣象
}
public IMenu levelTwo(Double area){
return new DecorationPackageMenu(area, "轻奢田园")
.appendCeiling(new LevelTwoCeiling()) // 吊顶,二级顶
.appendCoat(new LiBangCoat()) // 涂料,立邦
.appendTile(new MarcoPoloTile()); // 地砖,马可波罗
}
public IMenu levelThree(Double area){
return new DecorationPackageMenu(area, "现代简约")
.appendCeiling(new LevelOneCeiling()) // 吊顶,二级顶
.appendCoat(new LiBangCoat()) // 涂料,立邦
.appendTile(new DongPengTile()); // 地砖,东鹏
}
}
豪华欧式
、轻奢田园
、现代简约
,如果将来业务扩展也可以将这部分内容配置到数据库自动生成。但整体的思想还可以使用创建者模式进行搭建。3. 测试验证
@Test
public void test_Builder(){
Builder builder = new Builder();
// 豪华欧式
System.out.println(builder.levelOne(132.52D).getDetail());
// 轻奢田园
System.out.println(builder.levelTwo(98.25D).getDetail());
// 现代简约
System.out.println(builder.levelThree(85.43D).getDetail());
}
-------------------------------------------------------
装修清单
套餐等级:豪华欧式
套餐价格:198064.39 元
房屋面积:132.52 平米
材料清单:
吊顶:装修公司自带、二级顶、平米价格:850 元。
涂料:多乐士(Dulux)、第二代、平米价格:719 元。
地板:圣象、一级、平米价格:318 元。
-------------------------------------------------------
装修清单
套餐等级:轻奢田园
套餐价格:119865.00 元
房屋面积:98.25 平米
材料清单:
吊顶:装修公司自带、二级顶、平米价格:850 元。
涂料:立邦、默认级别、平米价格:650 元。
地砖:马可波罗(MARCO POLO)、缺省、平米价格:140 元。
-------------------------------------------------------
装修清单
套餐等级:现代简约
套餐价格:90897.52 元
房屋面积:85.43 平米
材料清单:
吊顶:装修公司自带、一级顶、平米价格:260 元。
涂料:立邦、默认级别、平米价格:650 元。
地砖:东鹏瓷砖、10001、平米价格:102 元。
Process finished with exit code 0
ifelse
里面。七、总结
一些基本物料不会变,而其组合经常变化的时候
,就可以选择这样的设计模式来构建代码。八、推荐阅读
重学 Java 设计模式:实战工厂方法模式
重学 Java 设计模式:实战抽象工厂模式
Java开发架构篇:初识领域驱动设计DDD落地
Java开发架构篇:DDD模型领域层决策规则树服务设计
Java开发架构篇:领域驱动设计架构基于SpringCloud搭建微服务
文章标题:重学 Java 设计模式:实战建造者模式
文章链接:http://soscw.com/index.php/essay/40714.html