当前位置: 首页 > news >正文

设计模式-建造者模式(代码实现、源码级别应用、使用场景)

提示:建造者模式的代码实现、建造者模式的使用场景、建造者模式源码级别的应用、建造者模式的优点、建造者模式的几种变形写法

文章目录

  • 前言
  • 一、定义
  • 二、类图
  • 三、代码实现
    • 3.1、建造者模式-第一种模式
      • 1、要建造的对象:
      • 2、对这个builder的抽象
      • 3.对抽象出来的方法的第一种实现
      • 4、是控制建造者模式中,具体的先builder啥,再builder啥的类
    • 3.2、建造者模式-第二种模式(第一种方式)
      • 1、代码
      • 2、测试类
    • 3、建造者模式-第二种模式(一种变种)
      • 1、代码
      • 2、测试类
  • 四、应用场景
  • 五、源码中的应用:
  • 总结


前言

随着时间的推移,我现在越来越感觉自己的代码不够优雅了,相信有一部分博友跟我有同样的困扰,因此决定再学习记录一下相关的设计模式。今天就介绍一下设计模式-建造者模式


一、定义

为了对应部分复杂对象,而创建出来的方法。(通常是跟一些不可变对象配合使用)
字段属性有一个顺序的要求,必须先做了哪个,然后才能做哪个。

二、类图

在这里插入图片描述

  • 右下角的product 可以简单的理解为,是一个复杂的对象。(要builder的对象)
  • builder是这个对象抽象出去的一些方法。
  • concreteBuilder是builder的具体的某一个实现
  • 具体的builder的逻辑,是由Director来控制(比如说第一步做哪些工作,第二部做哪些工作)

三、代码实现

3.1、建造者模式-第一种模式

1、要建造的对象:

package com.zheng.builder;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;/*** @author: ztl* @date: 2024/09/22 22:33* @desc: 这里指复杂对象*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Product {private String productName;private String companyName;private String part1;private String part2;private String part3;// ...
}

2、对这个builder的抽象

模式1中,对这个builder的抽象(就是要建造的复杂对象中,抽出来一部分公共的方法)

package com.zheng.builder.mode1;import com.zheng.builder.Product;/*** @author: ztl* @date: 2024/09/22 22:36* @desc: 模式1中,对这个builder的抽象(就是要建造的复杂对象中,抽出来一部分公共的方法)*/
public interface ProductBuilder {void builderProductName(String productName);void builderCompanyName(String companyName);void builderPart1(String part1);void builderPart2(String part2);void builderPart3(String part3);// 返回要建造的对象(上面不是set某写数学的逻辑嘛,最后肯定要返回一个要建造的对象)Product build();
}

3.对抽象出来的方法的第一种实现

代码如下(示例):

package com.zheng.builder.mode1;import com.zheng.builder.Product;/*** @author: ztl* @date: 2024/09/22 22:38* @desc: 抽象出来的方法中的,一个具体的实现*/
public class DefaultProductBuilder implements ProductBuilder{private String productName;private String companyName;private String part1;private String part2;private String part3;@Overridepublic void builderProductName(String productName) {this.productName = productName;}@Overridepublic void builderCompanyName(String companyName) {this.companyName = companyName;}@Overridepublic void builderPart1(String part1) {this.part1 = part1;}@Overridepublic void builderPart2(String part2) {this.part2 = part2;}@Overridepublic void builderPart3(String part3) {this.part3 = part3;}@Overridepublic Product build() {// 返回一个有参构造(这也可以理解,你类中有这些属性,你不返回有参构造,还能返回无参构造嘛)return new Product(productName,companyName,part1,part2,part3);}
}

4、是控制建造者模式中,具体的先builder啥,再builder啥的类

package com.zheng.builder.mode1;import com.zheng.builder.Product;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;/*** @author: ztl* @date: 2024/09/22 22:41* @desc: 是控制建造者模式中,具体的先builder啥,再builder啥的类*/@Data
@AllArgsConstructor
@NoArgsConstructor
public class Director {private ProductBuilder builder;/*** 具体的builder步骤,先干嘛,在干嘛,最后干嘛* @return*/public Product makeProduct(String productName,String companyName,String part1,String part2,String part3){// 先构建companyName,builder.builderCompanyName(companyName);// 有companyName了再构建productName,builder.builderProductName(productName);builder.builderPart1(part1);builder.builderPart2(part2);builder.builderPart3(part3);// ...// 这里看的build中没任何参数,其中他的build方法会把所有的属性都带上return builder.build();}
}

3.2、建造者模式-第二种模式(第一种方式)

1、代码

package com.zheng.builder.mode1;import com.zheng.builder.Product;/*** @author: ztl* @date: 2024/09/22 22:38* @desc: 抽象出来的方法中的,第二个具体的实现*/
public class TwoProductBuilder implements ProductBuilder{private String productName;private String companyName;private String part1;private String part2;private String part3;@Overridepublic void builderProductName(String productName) {this.productName = productName+"123";}@Overridepublic void builderCompanyName(String companyName) {this.companyName = companyName;}@Overridepublic void builderPart1(String part1) {this.part1 = part1+"123";}@Overridepublic void builderPart2(String part2) {this.part2 = part2;}@Overridepublic void builderPart3(String part3) {this.part3 = part3;}@Overridepublic Product build() {// 返回一个有参构造(这也可以理解,你类中有这些属性,你不返回有参构造,还能返回无参构造嘛)return new Product(productName,companyName,part1,part2,part3);}
}

2、测试类

package com.zheng.builder;import com.zheng.builder.mode1.DefaultProductBuilder;
import com.zheng.builder.mode1.Director;
import com.zheng.builder.mode1.ProductBuilder;
import com.zheng.builder.mode1.TwoProductBuilder;/*** @author: ztl* @date: 2024/09/22 22:34* @desc:*/
public class BuilderTest {public static void main(String[] args) {// 对于Product这个复杂对象,我们正常的构建怎么构建呢:Product product = new Product();product.setProductName("00");product.setCompanyName("..");// ...// 模式1的建造者demo:ProductBuilder defaultProductBuilder = new DefaultProductBuilder();// 建造者模式中不是需要一个具体的实现嘛,这是就是其中一个具体实现,你可以有第二个具体实现Director director = new Director(defaultProductBuilder);Product product1 = director.makeProduct("pname", "cname", "par1", "2", "4");System.out.println(product1); // Product(productName=pname, companyName=cname, part1=par1, part2=2, part3=4)// 模式1的建造者demo2:ProductBuilder twoProductBuilder = new TwoProductBuilder();// 建造者模式中不是需要一个具体的实现嘛,这是就是其中一个具体实现,你可以有第二个具体实现Director director2 = new Director(twoProductBuilder);Product product2 = director2.makeProduct("pname", "cname", "par1", "2", "4");
//        System.out.println(product2); // Product(productName=pname123, companyName=cname, part1=par1123, part2=2, part3=4)}
}

3、建造者模式-第二种模式(一种变种)

建造者模式的一个变种,当没那么复杂的时候,可以用这个方式(通常是配合不可变对象一起使用):

1、代码

package com.zheng.builder.mode2;/*** @author: ztl* @date: 2024/09/23 22:24* @desc: 建造者模式变种,的测试类*/
public class Product2Test {public static void main(String[] args) {// 可以:Product2 build = new Product2.Builder().companyName("1").productName("332").build();System.out.println(build);// 也可以:Product2.Builder builder = new Product2.Builder();builder.productName("nihap");builder.part1("1");builder.part2("3");Product2 build2 = builder.build();System.out.println(build2);}
}

2、测试类

package com.zheng.builder.mode2;/*** @author: ztl* @date: 2024/09/23 22:24* @desc: 建造者模式变种,的测试类*/
public class Product2Test {public static void main(String[] args) {// 可以:Product2 build = new Product2.Builder().companyName("1").productName("332").build();System.out.println(build);// 也可以:Product2.Builder builder = new Product2.Builder();builder.productName("nihap");builder.part1("1");builder.part2("3");Product2 build2 = builder.build();System.out.println(build2);}
}

四、应用场景

1.需要生成的对象具有复杂的内部结构
2.需要生成的对象内部属性本身互相依赖
3.与不可变对象配合使用

优点:
1.建造者独立,易扩展
2.便于控制细节风险

五、源码中的应用:

org.springframework.web.servlet.mvc.method.RequestMappingInfo;
org.springframework.beans.factory.support.BeanDefinitionBuilder;

总结

其实我总感觉这些设计模式,都一个套路:抽出来公共的,然后去复用公共的。


http://www.mrgr.cn/news/62274.html

相关文章:

  • layui扩展组件之----右键菜单
  • 春季测试 2023 我的题解
  • camera和lidar外参标定
  • QT——串口调试助手
  • 基于LT7689开发的TFT串口屏控制方案-3D打印机
  • mac系统升级node版本
  • At dp综合
  • 算法训练(leetcode)二刷第十三天 | 110. 平衡二叉树、*257. 二叉树的所有路径、404. 左叶子之和、*222. 完全二叉树的节点个数
  • #渗透测试#SRC漏洞挖掘# 信息收集-Shodan之网页版
  • 面试简历技巧分享
  • threejs开源实例-粒子地球
  • SSH免密钥登录
  • 分布式架构搭建博客网站
  • https加密过程详解
  • CountDownLatch与CyclicBarrier的比较应用
  • 头歌网络安全爬虫
  • Redis 发布订阅 总结
  • 图像篡改研究
  • 未来生活中的AI电脑是怎样的
  • 【Python单元测试】pytest框架单元测试常用用例
  • Go性能基础
  • 【股东权益与市值:概念、计算与差异分析】
  • 关于防止布局底部有弹簧而导致的QWidget闪烁问题
  • 12-Docker发布微服务
  • STM32的隐藏定时器---DWT
  • 为什么大模型都是Decoder-only结构?