千家信息网

设计模式系列之如何使用建造者模式

发表于:2024-09-22 作者:千家信息网编辑
千家信息网最后更新 2024年09月22日,这篇文章主要讲解了"设计模式系列之如何使用建造者模式",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"设计模式系列之如何使用建造者模式"吧!1、概述建造者
千家信息网最后更新 2024年09月22日设计模式系列之如何使用建造者模式

这篇文章主要讲解了"设计模式系列之如何使用建造者模式",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"设计模式系列之如何使用建造者模式"吧!

1、概述

建造者模式是一种创建型设计模式, 使你能够分步骤创建复杂对象。该模式允许你使用相同的创建代码生成不同类型和形式的对象。

2、适用场景

1)避免重叠构造函数,例如:一个类有很多的属性,这时候的构造方法需要传递很多的参数,为了避免这样,会重新写一个相对参数较少的构造方法,但是仍然需要对其他参数进行赋默认值。

2)当需要创建不同的产品类型,此处指比较接近的产品类型,则可以在顶层builder中包含大部分产品属性的赋值方法。

3、实例

有以下场景,我们分别使用常规方式和建造者模式实现:

当前有一个汽车工厂,可以生产的汽车类型有ordinary,sport。 除了汽车之外,同样可以生产汽车的操作手册manual。 汽车有以下的属性: 1、type 类型 2、seats 座位数 3、engine 引擎 4、GPS 导航  分别实现汽车和手册的生产过程

不使用建造者模式

分别创建车car和手册manual,以及其内部的属性,当前例子中车和手册是相同的属性。

@Data public class Car {      private CarType type;      private int seats;      private Engine engine;      private GPS GPS;      public Car(CarType type, int seats, Engine engine, com.cloud.bssp.designpatterns.builder.withouttdesign.entity.GPS GPS) {         this.type = type;         this.seats = seats;         this.engine = engine;         this.GPS = GPS;     }      public void detail() {         System.out.println("this is " + type + " car");         System.out.println("the seats is :" + seats);         System.out.println("the engine is :" + engine);         System.out.println("this GPS is :" + GPS);     } }
@Data public class Manual {      private CarType type;      private int seats;      private Engine engine;      private GPS GPS;      public Manual(CarType type, int seats, Engine engine, com.cloud.bssp.designpatterns.builder.withouttdesign.entity.GPS GPS) {         this.type = type;         this.seats = seats;         this.engine = engine;         this.GPS = GPS;     }      public void detail() {         System.out.println("this is " + type + " car");         System.out.println("the seats is :" + seats);         System.out.println("the engine is :" + engine);         System.out.println("this GPS is :" + GPS);     } }
public enum CarType {     SPORT,ORDINARY; }
/**  * 汽车引擎  */ @Data public class Engine {      /**      * 排量      */     private final double volume;     /**      * 里程      */     private double mileage;      public Engine(double volume, double mileage) {         this.volume = volume;         this.mileage = mileage;     } }
@Data public class GPS {     /**      * 路线      */     private String route;      public GPS(String route) {         this.route = route;     } }

测试类:

/**  * 客户端  */ @RunWith(SpringRunner.class) @SpringBootTest(classes = TestApplication.class) public class TestDemo {      @Test     public void test() {         //生产跑车         Car sportCar = new Car(                 CarType.SPORT,                 2,                 new Engine(3.0, 0),                 new GPS("上海东方明珠塔到上海动物园")         );         sportCar.detail();         System.out.println("----------------------------------------");         //生产普通汽车         Car ordinaryCar = new Car(                 CarType.ORDINARY,                 4,                 new Engine(2.0, 0),                 new GPS("上海东方明珠塔到上海动物园")         );         ordinaryCar.detail();         System.out.println("----------------------------------------");         //生产汽车操作手册         Manual manual = new Manual(                 CarType.ORDINARY,                 4,                 new Engine(2.0, 0),                 new GPS("上海东方明珠塔到上海动物园")         );         manual.detail();         System.out.println("----------------------------------------");     } }

结果:

this is SPORT car the seats is :2 the engine is :Engine(volume=3.0, mileage=0.0) this GPS is :GPS(route=上海东方明珠塔到上海动物园) ---------------------------------------- this is ORDINARY car the seats is :4 the engine is :Engine(volume=2.0, mileage=0.0) this GPS is :GPS(route=上海东方明珠塔到上海动物园) ---------------------------------------- this is ORDINARY car the seats is :4 the engine is :Engine(volume=2.0, mileage=0.0) this GPS is :GPS(route=上海东方明珠塔到上海动物园) ----------------------------------------

使用建造者模式实现

使用建造者模式后,代码要比上面的方法多了不少:

创建顶层Builder

public interface Builder {      void setCarType(CarType carType);      void setSeats(int seats);      void setEngine(Engine engine);      void setGPS(GPS gps); }

创建实体类,与上面是相同的,这里不重复了。

创建car的builder:

@Data public class CarBuilder implements Builder {      private CarType carType;      private int seats;      private Engine engine;      private GPS GPS;      public Car getResult() {         return new Car(carType, seats, engine, GPS);     } }

创建汽车操作手册builder:

@Data public class ManualBuilder implements Builder {      private CarType carType;      private int seats;      private Engine engine;      private GPS GPS;      public Manual getResult() {         return new Manual(carType, seats, engine, GPS);     } }

创建一个builder管理器:

public class Director {      public void constructSportsCar(Builder builder) {         builder.setCarType(CarType.SPORT);         builder.setSeats(2);         builder.setEngine(new Engine(3.0, 0));         builder.setGPS(new GPS("上海东方明珠塔到上海动物园"));     }      public void constructOrdinaryCar(Builder builder) {         builder.setCarType(CarType.ORDINARY);         builder.setSeats(4);         builder.setEngine(new Engine(2.0, 0));         builder.setGPS(new GPS("上海东方明珠塔到上海动物园"));     } }

测试类:

@RunWith(SpringRunner.class) @SpringBootTest(classes = TestApplication.class) public class TestDemo {      @Test     public void test() {         Director director = new Director();         //生产跑车         CarBuilder carBuilder = new CarBuilder();         director.constructSportsCar(carBuilder);         Car sportCar = carBuilder.getResult();         sportCar.detail();         System.out.println("-----------------------------------");          //生产普通汽车         director.constructOrdinaryCar(carBuilder);         Car ordinaryCar = carBuilder.getResult();         ordinaryCar.detail();         System.out.println("-----------------------------------");          //生产汽车操作手册         ManualBuilder manualBuilder = new ManualBuilder();         director.constructOrdinaryCar(manualBuilder);         Manual manual = manualBuilder.getResult();         manual.detail();         System.out.println("-----------------------------------");     } }

结果:

this is SPORT car the seats is :2 the engine is :Engine(volume=3.0, mileage=0.0) this GPS is :GPS(route=上海东方明珠塔到上海动物园) ----------------------------------- this is ORDINARY car the seats is :4 the engine is :Engine(volume=2.0, mileage=0.0) this GPS is :GPS(route=上海东方明珠塔到上海动物园) ----------------------------------- this Manual ORDINARY car the Manual seats is :4 the Manual engine is :Engine(volume=2.0, mileage=0.0) this GManual PS is :GPS(route=上海东方明珠塔到上海动物园) -----------------------------------

4、分析

建造者模式基本有以下几个角色:

如上面两种方式的结果显示,都可以实现生产汽车和汽车手册。

结果没什么差异。

在没使用建造者的方式中:

生产汽车的参数是由客户端自己指定的,并且需要传很多的参数,实际工作中可能需要更多的参数,可能有部分参数是不需要的。

使用建造者模式

用户不需要去具体指定多个参数了,对于客户端更友好。

builder:将产品new()提出到builder中,提供产品所拥有的属性设置方法,一类产品都可以使用这个builder进行产品创建。

director:作为builder的管理者,主要控制产品的属性设置,在这个类中,具体指定除了可以生产的产品的构造,并且对属性进行赋值,最终返回一个用户需要的builder。

客户端调用只需要创建需要的产品类型builder,通过管理者director对builder进行属性设置,最终客户端通过调用builder的方法获取最终需要的产品。

极大程度减少并优化的客户端的代码,同时由管理者director限制了产品的种类。

从扩展层层面看:

未使用建造者:增加对应的产品类,客户端直接new。

使用建造者模式:增加builder,并且在director增加可创建的产品的builder构造。

5、总结

最后总结下上面例子中使用抽象工厂方法的优缺点:

优点:

1)遵守单一原则。

2)不同产品,可复用相同的产品创建流程。

3)简化客户端调用方式。去除多参构造的方式。

4)分步骤创建对象。

缺点:

增加多个类,代码复杂度增加。

感谢各位的阅读,以上就是"设计模式系列之如何使用建造者模式"的内容了,经过本文的学习后,相信大家对设计模式系列之如何使用建造者模式这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

上海 模式 产品 汽车 生产 动物园 明珠 上海动物园 东方明珠塔 属性 参数 客户 手册 客户端 方法 类型 设计模式 设计 方式 生产汽车 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 网络技术服务开票税点 安卓软件开发的毕业论文 虹口区专业软件开发质量保障 ic软件开发工程师 描述数据库技术的发展历程 恒为服务器制造 三维建模数据库失败 为什么想学计算机网络技术 安徽浪潮服务器代理云主机 access数据库管理图片 北京运营软件开发公司 长沙搜房网络技术有限公司 北京服务器防火墙好不好 网络安全密码与口令的概念 广州分创互联网科技有限公司 智慧树数据库单元测试 软件开发制作辅助工具 方舟端游联机搜索不到服务器 住建局网络安全年度工作计划 在软件开发中 有哪些阶段 mc的服务器怎么装模组 关于网络安全我能做什么 软件开发的知识产权年限 数据库热迁移 河北省清河县软件开发 怎么侵入数据库 网络安全德育实践课PPT 广州的网络安全问题 卧龙吟2服务器开放时间 方舟端游联机搜索不到服务器
0