当前位置: 首页 > 科技观察

设计模式系列

时间:2023-03-21 12:13:08 科技观察

的建造者模式本文转载自微信公众号《狼王编程》,作者狼王。转载本文请联系狼王编程公众号。1.概述建造者模式是一种创建型设计模式,可以让你一步一步地创建复杂的对象。此模式允许您使用相同的创建代码来生成不同类型和形式的对象。2、适用场景1)避免构造函数重叠。例如,一个类有很多属性。这时候构造方法需要传递很多参数。为了避免这种情况,会重写一个参数比较少的构造方法,但是仍然需要给其他参数赋默认值。2)当需要创建不同的产品类型时,这里指的是比较接近的产品类型,可以在顶层构建器中包含大部分产品属性的赋值方法。3、示例有以下场景,我们分别使用常规方式和建造者方式实现:目前有一家汽车厂,可以生产的车型有普通款和运动款。除了汽车,还可以生产汽车的说明书。小车有以下属性:1.类型2.座位数3.发动机4.GPS导航分别实现小车和说明书的制作过程,无需使用建造者模式分别创建小车和说明书,以及他们的内部属性。在当前示例中,car和manual是相同的属性。@DatapublicclassCar{privateCarTypetype;privateintseats;privateEngineengine;privateGPSGPS;publicCar(CarTypetype,intseats,Engineengine,com.cloud.bssp.designpatterns.builder.withouttdesign.entity.GPSGPS){this.type=type;this.seats=seats;this.engine=engine;this.GPS=GPS;}publicvoiddetail(){System.out.println("thisis"+type+"car");System.out.println("theseats:"+seats);System.out.println("theengineis:"+engine);System.out.println("thisGPSis:"+GPS);}}@DatapublicclassManual{privateCarTypetype;privateintseats;privateEngineengine;privateGPSGPS;publicManual(CarTypetype,intseats,Engineengine,com.cloud.bssp.designpatterns.builder.withouttdesign.entity.GPSGPS){this.type=type;this.seats=seats;this.engine=engine;this.GPS=GPS;}publicvoiddetail(){System.out.println("thisis"+type+"car");System.out.println("theseatsis:"+seats);System.out.println("theengineis:"+engine);System.out.println("thisGPisis:"+GPS);}}publicenumCarType{SPORT,ORDINARY;}/***carengine*/@DatapublicclassEngine{/***displacement*/privatefinaldoublevolume;/***mileage*/privatedoublemileage;publicEngine(doublevolume,doublemileage){this.volume=volume;this.mileage=mileage;}}@DatapublicclassGPS{/***route*/privateStringroute;publicGPS(Stringroute){this.route=route;}}测试类:/***Client*/@RunWith(SpringRunner.class)@SpringBootTest(classes=TestApplication.class)publicclassTestDemo{@Testpublicvoidtest(){//量产跑车CarsportCar=newCar(CarType.SPORT,2,newEngine(3.0,0),newGPS("上海东方明珠塔到上海动物园"));sportCar.detail();System.out.println("--------------------------------------");//生产普通车CarordinaryCar=newCar(CarType.ORDINARY,4,newEngine(2.0,0),newGPS("上海东方明珠塔到上海动物园"));ordinaryCar.detail();System.out.println("------------------------------------------");//小车操作手册制作Manualmanual=newManual(CarType.ORDINARY,4,newEngine(2.0,0),newGPS("上海东方明珠到上海动物园"));manual.detail();System.out.println("-----------------------------------------");}}Result:thisisSPORTcartheseatsis:2theengineis:Engine(volume=3.0,mileage=0.0)thisGPSis:GPS(route=ShanghaiOrientalPearlTowertoShanghaiZoo)-----------------------------------------thisisORDINARYcartheseatsis:4theengineis:Engine(volume=2.0,mileage=0.0)thisGPSis:GPS(route=ShanghaiOrientalPearlTower到上海动物园)------------------------------------thisisORDINARYcartheseatsis:4theengineis:Engine(volume=2.0,mileage=0.0)thisGPisis:GPS(route=上海东方明珠塔到上海动物园)----------------------------------------使用builder模式实现使用builder模式后,代码比上面的方法多了很多:创建顶层BuilderpublicinterfaceBuilder{voidsetCarType(CarTypecarType);voidsetSeats(intseats);voidsetEngine(引擎引擎);voidsetGPS(GPSgps);}创建一个实体类,同上,这里不再赘述创建汽车生成器:@DatapublicclassCarBuilderimplementsBuilder{privateCarTypecarType;privateintseats;privateEngineengine;privateGPGPPS;publicCargetResult(){returnnewCar(carType,seats,engine,GPS);}}创建汽车操作手册生成器:@DatapublicclassGPSManualBuilderimplementsBuilder{privateCarTypecarType;privateintseats;privateintseatspublicManualgetResult(){returnnewManual(carType,seats,engine,GPS);}}创建构建器管理器:publicclassDirector{publicvoidconstructSportsCar(Builderbuilder){builder.setCarType(CarType.SPORT);builder.setSeats(2);builder.setEngine(newEngine(3.0,0));builder.setGPS(newGPS("上海东方明珠塔到上海动物园"));}publicvoidconstructOrdinaryCar(Builderbuilder){builder.setCarType(CarType.ORDINARY);builder.setSeats(4);builder.setEngine(newEngine(2.0,0));builder.setGPS(newGPS("上海东方明珠塔到上海动物园"));}}测试类:@RunWith(SpringRunner.class)@SpringBootTest(classes=TestApplication.class)publicclassTestDemo{@Testpublicvoidtest(){Directordirector=newDirector();//生产跑车CarBuildercarBuilder=newCarBuilder();director.constructSportsCar(carBuilder);CarsportCar=carBuilder.getResult();sportCar.detail();System.out.println("----------------------------------");//生产普通汽车director.constructOrdinaryCar(carBuilder);CarordinaryCar=carBuilder.getResult();ordinaryCar.detail();System.out.println("--------------------------------");//量产车ManualBuildermanualBuilder=newManualBuilder();director.constructOrdinaryCar(manualBuilder);Manualmanual=manualBuilder.getResult();manual.detail();System.out.println("-------------------------------");}}Result:thisisSPORTcartheseatsis:2theengineis:Engine(volume=3.0,mileage=0.0)thisGPSis:GPS(route=ShanghaiOrientalPearlTowertoShanghaiZoo)--------------------------------thisisORDINARYcartheseatsis:4theengineis:Engine(volume=2.0,mileage=0.0)thisGPSis:GPS(route=上海东方明珠塔到上海动物园)--------------------------------------本手册ORDINARYcartheManualseatsis:4theManualengineis:Engine(volume=2.0,mileage=0.0)thisGManualPSis:GPS(route=上海东方明珠塔到上海动物园)-----------------------------------4。分析建造者模式主要有以下作用:从以上两种方式的结果可以看出,生产汽车和汽车说明书的结果没有区别。不使用builder的方式:量产车的参数由客户自己指定,需要传递很多参数。在实际工作中,可能需要的参数较多,也可能不需要某些参数。使用构建器模式,用户无需指定多个参数,对客户端更加友好。builder:向builder提出产品new(),并提供产品拥有的属性设置方法。所有类型的产品都可以使用此构建器来创建产品。director:作为builder的管理者,主要控制产品的属性设置。在这个类中,它指定了可以生产的产品的结构,为属性赋值,最后返回一个用户需要的构建器。客户端调用只需要创建需要的产品类型builder,通过manager-director设置builder的属性,最后客户端通过调用builder方法获取最终需要的产品。客户端代码大幅缩减优化,产品种类受经理总监限制。从扩展层来看:没有使用builder:添加了相应的商品类目,直接新建client。使用建造者模式:增加建造者,在director中增加可创建产品的建造者结构。5.总结最后总结一下上面例子中使用抽象工厂方法的优缺点:优点:1)遵守单一原则。2)不同的产品可以复用相同的产品创建过程。3)简化客户端调用方式。删除多参数结构的方法。4)逐步创建对象。缺点:添加多个类会增加代码复杂度。