乱码七糟[luànqībāzāo],我时常怀疑这个成语是来形容程序猿的!
无论承接什么样的需求,是不是身边总有那么几个人代码写的烂,但是却时常有测试小姐姐过来聊天(求改bug)、有产品小伙伴送吃的(求写需求)、有业务小妹妹陪着改代码(求上线),直至领导都认为他的工作很重要,而在旁边的你只能蹭点吃的。
那你说,CRUD的代码还想让我怎么样?
这样的小伙伴,可能把代码写的很直接,ifelse多用一点,满足于先临时支持一下,想着这也没什么的。而且这样的业务需求要的急又都是增删改查的内容,实在不想做设计。而如果有人提到说好好设计下,可能也会被反对不要过渡设计。
贴膏药似的修修补补,一次比一次恐怖!
第一次完成产品需求实在是很快,但互联网的代码不比传统企业。在传统行业可能一套代码能用十年,但在互联网高速的迭代下你的工程,一年就要变动几十次。如果从一开始就想着只要完成功能就可以,那么随之而来的是后续的需求难以承接,每次看着成片成片的代码,实在不知如何下手。
在研发流程规范下执行,才能写出好程序!
一个项目的上线往往要经历业务需求、产品设计、研发实现、测试验证、上线部署到正式开量,而这其中对研发非常重要的一换就是研发实现的过程,又可以包括为;架构选型、功能设计、设计评审、代码实现、代码评审、单测覆盖率检查、编写文档、提交测试。所以在一些流程规范下,其实很难让你随意开发代码。
开发代码的过程不是炫技,就像盖房子如果不按照图纸来修建,回首就在山墙上搭一个厨房卫浴!可能在现实场景中这很荒唐,但在功能开发中却总有这样的代码。
所以我们也需要一些设计模式的标准思想,去建设代码结构,提升全局把控能力。
建造者模式所完成的内容就是通过将多个简单对象通过一步步的组装构建出一个复杂对象的过程。
那么,哪里有这样的场景呢?
例如你玩王者荣耀的时的初始化界面;有三条路、有树木、有野怪、有守卫塔等等,甚至依赖于你的网络情况会控制清晰度。而当你换一个场景进行其他不同模式的选择时,同样会建设道路、树木、野怪等等,但是他们的摆放和大小都有不同。这里就可以用到建造者模式来初始化游戏元素。
而这样的根据相同的物料,不同的组装所产生出的具体的内容,就是建造者模式的最终意图,也就是;将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
这里我们模拟装修公司对于设计出一些套餐装修服务的场景。
很多装修公司都会给出自家的套餐服务,一般有;欧式豪华、轻奢田园、现代简约等等,而这些套餐的后面是不同的商品的组合。例如;一级&二级吊顶、多乐士涂料、圣象地板、马可波罗地砖等等,按照不同的套餐的价格选取不同的品牌组合,最终再按照装修面积给出一个整体的报价。
这里我们就模拟装修公司想推出一些套餐装修服务,按照不同的价格设定品牌选择组合,以达到使用建造者模式的过程。
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(地砖),这么四项内容。(实际的装修物料要比这个多的多)
publicinterfaceMatter{Stringscene();//场景;地板、地砖、涂料、吊顶Stringbrand();//品牌Stringmodel();//型号BigDecimalprice();//价格Stringdesc();//描述}2.2吊顶(ceiling)一级顶
publicclassLevelOneCeilingimplementsMatter{publicStringscene(){return"吊顶";}publicStringbrand(){return"装修公司自带";}publicStringmodel(){return"一级顶";}publicBigDecimalprice(){returnnewBigDecimal(260);}publicStringdesc(){return"造型只做低一级,只有一个层次的吊顶,一般离顶120-150mm";}}二级顶
publicclassLevelTwoCeilingimplementsMatter{publicStringscene(){return"吊顶";}publicStringbrand(){return"装修公司自带";}publicStringmodel(){return"二级顶";}publicBigDecimalprice(){returnnewBigDecimal(850);}publicStringdesc(){return"两个层次的吊顶,二级吊顶高度一般就往下吊20cm,要是层高很高,也可增加每级的厚度";}}2.3涂料(coat)多乐士
publicclassDuluxCoatimplementsMatter{publicStringscene(){return"涂料";}publicStringbrand(){return"多乐士(Dulux)";}publicStringmodel(){return"第二代";}publicBigDecimalprice(){returnnewBigDecimal(719);}publicStringdesc(){return"多乐士是阿克苏诺贝尔旗下的著名建筑装饰油漆品牌,产品畅销于全球100个国家,每年全球有5000万户家庭使用多乐士油漆。";}}立邦
publicclassLiBangCoatimplementsMatter{publicStringscene(){return"涂料";}publicStringbrand(){return"立邦";}publicStringmodel(){return"默认级别";}publicBigDecimalprice(){returnnewBigDecimal(650);}publicStringdesc(){return"立邦始终以开发绿色产品、注重高科技、高品质为目标,以技术力量不断推进科研和开发,满足消费者需求。";}}2.4地板(floor)德尔
publicclassDerFloorimplementsMatter{publicStringscene(){return"地板";}publicStringbrand(){return"德尔(Der)";}publicStringmodel(){return"A+";}publicBigDecimalprice(){returnnewBigDecimal(119);}publicStringdesc(){return"DER德尔集团是全球领先的专业木地板制造商,北京2008年奥运会家装和公装地板供应商";}}圣象
publicclassShengXiangFloorimplementsMatter{publicStringscene(){return"地板";}publicStringbrand(){return"圣象";}publicStringmodel(){return"一级";}publicBigDecimalprice(){returnnewBigDecimal(318);}publicStringdesc(){return"圣象地板是中国地板行业著名品牌。圣象地板拥有中国驰名商标、中国名牌、国家免检、中国环境标志认证等多项荣誉。";}}2.5地砖(tile)东鹏
publicclassDongPengTileimplementsMatter{publicStringscene(){return"地砖";}publicStringbrand(){return"东鹏瓷砖";}publicStringmodel(){return"10001";}publicBigDecimalprice(){returnnewBigDecimal(102);}publicStringdesc(){return"东鹏瓷砖以品质铸就品牌,科技推动品牌,口碑传播品牌为宗旨,2014年品牌价值132.35亿元,位列建陶行业榜首。";}}马可波罗
publicclassMarcoPoloTileimplementsMatter{publicStringscene(){return"地砖";}publicStringbrand(){return"马可波罗(MARCOPOLO)";}publicStringmodel(){return"缺省";}publicBigDecimalprice(){returnnewBigDecimal(140);}publicStringdesc(){return"“马可波罗”品牌诞生于1996年,作为国内最早品牌化的建陶品牌,以“文化陶瓷”占领市场,享有“仿古砖至尊”的美誉。";}}五、用一坨坨代码实现讲道理没有ifelse解决不了的逻辑,不行就在加一行!
每一个章节中我们都会使用这样很直白的方式去把功能实现出来,在通过设计模式去优化完善。这样的代码结构也都是非常简单的,没有复杂的类关系结构,都是直来直去的代码。除了我们经常强调的这样的代码不能很好的扩展外,做一些例子demo工程还是可以的。
itstack-demo-design-3-01└──src└──main└──java└──org.itstack.demo.design└──DecorationPackageController.java一个类几千行的代码你是否见过,嚯?那今天就让你见识一下有这样潜质的类!
编写测试类:
@Testpublicvoidtest_DecorationPackageController(){DecorationPackageControllerdecoration=newDecorationPackageController();//豪华欧式System.out.println(decoration.getMatterList(newBigDecimal("132.52"),1));//轻奢田园System.out.println(decoration.getMatterList(newBigDecimal("98.25"),2));//现代简约System.out.println(decoration.getMatterList(newBigDecimal("85.43"),3));}结果:
-------------------------------------------------------装修清单套餐等级:1套餐价格:198064.39元房屋面积:132.52平米材料清单:吊顶:装修公司自带、二级顶、平米价格:850元。涂料:多乐士(Dulux)、第二代、平米价格:719元。地板:圣象、一级、平米价格:318元。-------------------------------------------------------装修清单套餐等级:2套餐价格:119865.00元房屋面积:98.25平米材料清单:吊顶:装修公司自带、二级顶、平米价格:850元。涂料:立邦、默认级别、平米价格:650元。地砖:马可波罗(MARCOPOLO)、缺省、平米价格:140元。-------------------------------------------------------装修清单套餐等级:3套餐价格:90897.52元房屋面积:85.43平米材料清单:吊顶:装修公司自带、一级顶、平米价格:260元。涂料:立邦、默认级别、平米价格:650元。地砖:东鹏瓷砖、10001、平米价格:102元。Processfinishedwithexitcode0六、建造者模式重构代码接下来使用建造者模式来进行代码优化,也算是一次很小的重构。
建造者模式主要解决的问题是在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的过程构成;由于需求的变化,这个复杂对象的各个部分经常面临着重大的变化,但是将它们组合在一起的过程却相对稳定。
这里我们会把构建的过程交给创建者类,而创建者通过使用我们的构建工具包,去构建出不同的装修套餐。
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实现方式相比,多出来了两个二外的类。具体功能如下;
好,那么接下来会分别讲解几个类的具体实现。
@Testpublicvoidtest_Builder(){Builderbuilder=newBuilder();//豪华欧式System.out.println(builder.levelOne(132.52D).getDetail());//轻奢田园System.out.println(builder.levelTwo(98.25D).getDetail());//现代简约System.out.println(builder.levelThree(85.43D).getDetail());}