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

java设计模式三、创建者模式

概念与定义

创建者模式(Builder Pattern)是一种设计模式,属于创建型模式的一种。它的核心思想是将一个复杂对象的构造与其表示分离,使得同样的构建过程可以创建不同的表示。这种模式通过将复杂对象分解为多个相对简单的部分,然后一步一步构建而成,从而提高了代码的灵活性和可读性。

简单来说,创建者模式就像是建筑工程师与施工队的关系:工程师负责设计蓝图和施工步骤(构建过程),而施工队根据蓝图一步步施工(创建对象),最终完成建筑(复杂对象)。这种分离使得我们能够更容易地管理复杂对象的创建过程,特别是在对象有很多组成部分或配置选项时。

适用场景分析

创建者模式特别适用于以下场景:

  1. 对象具有多个组成部分:当对象由多个部分组成,且每个部分可能有不同的实现或配置时。
  2. 需要创建不同的对象表示:同样的构建过程需要产生不同的结果对象。
  3. 避免构造函数参数过多:当构造函数参数过多或可选参数复杂时,使用创建者模式可以提高代码的可读性和易用性。
  4. 对象创建过程需要精细化控制:当对象的创建步骤需要精确控制,或者某些步骤需要根据不同情况省略或添加时。

在本文中,我们将通过一个汽车制造的示例来详细讲解创建者模式的应用。

示例场景:汽车制造

假设我们正在设计一个汽车制造系统,汽车由多个零件组成,包括车窗、座椅和轮胎。每种零件又分为A、B两种类型,分别对应不同的配置和价格。我们需要能够灵活地创建不同类型的汽车(如A型车、B型车),并且能够方便地扩展新的类型。

原始实现方式及其问题

首先,我们来看一种简单的实现方式。我们定义一个Matter接口表示汽车零件,然后为每种零件创建实现类(如AseatsBseats等)。最后,在一个创建类(如Ycreate)中通过条件判断来组装不同类型的汽车。

零件接口定义
package com.YA33.desgin.creator;import java.math.BigDecimal;public interface Matter {String scene();      // 使用场景String brand();      // 品牌String model();      // 型号BigDecimal price();  // 价格String desc();       // 描述
}
具体零件实现

以座椅为例,A类和B类座椅的实现如下:

package com.YA33.desgin.creator.seats;import com.YA33.desgin.creator.Matter;
import java.math.BigDecimal;public class Aseats implements Matter {@Overridepublic String scene() { return "A类座椅"; }@Overridepublic String brand() { return "原车自带"; }@Overridepublic String model() { return "A级"; }@Overridepublic BigDecimal price() { return new BigDecimal(0); }@Overridepublic String desc() { return "A类座椅原车自带,适配好,不需要额外消费"; }
}public class Bseats implements Matter {@Overridepublic String scene() { return "B类座椅"; }@Overridepublic String brand() { return "需要您额外购买"; }@Overridepublic String model() { return "S级"; }@Overridepublic BigDecimal price() { return new BigDecimal(10000); }@Overridepublic String desc() { return "B类座椅原采用荷兰小牛皮,舒适度高"; }
}
原始创建类
package com.YA33.desgin.creator;import com.YA33.desgin.creator.seats.Aseats;
import com.YA33.desgin.creator.seats.Bseats;
// 其他零件导入略import java.math.BigDecimal;
import java.util.ArrayList;public class Ycreate {public String getCar(String type) {ArrayList<Matter> list = new ArrayList<>();BigDecimal price = new BigDecimal(10000); // 基础价格if ("A".equals(type)) {Aseats aseats = new Aseats();Atries atries = new Atries();Awindows awindows = new Awindows();list.add(aseats);list.add(atries);list.add(awindows);BigDecimal extraPrice = aseats.price().add(atries.price()).add(awindows.price());return list + "总价格" + price.add(extraPrice);} else if ("B".equals(type)) {// 类似A类型的处理,略} else {return null;}}
}
原始方式存在的问题
  1. 代码重复:A型和B型车的创建代码几乎完全相同,只有具体零件类型不同。
  2. 难以扩展:如果需要新增C型、D型车,必须修改getCar方法,添加更多的条件分支,违反开闭原则。
  3. 可读性差:当零件类型增多时,条件判断会变得冗长且难以维护。
  4. 构建过程固化:构建过程与具体零件类型紧密耦合,无法灵活调整构建步骤。

创建者模式的解决方案

为了解决上述问题,我们引入创建者模式。创建者模式通过将对象的构建过程抽象出来,使得我们可以通过不同的构建器来创建不同的对象表示。

模式结构

创建者模式通常包含以下几个角色:

  1. 产品(Product):要创建的复杂对象,在本文中是汽车。
  2. 抽象建造者(Builder):定义创建产品各个部分的抽象接口,在本文中是IMenu
  3. 具体建造者(ConcreteBuilder):实现抽象建造者接口,构建和装配各个部件,在本文中是CarPackgeMenu
  4. 指挥者(Director):调用具体建造者来构建产品,它负责管理构建过程,在本文中是Builder类。

下面是创建者模式的结构示意图:

+----------------+       +-----------------+       +-------------------+
|   Director     |       |   Builder       |       |    Product        |
| (Builder类)    |------>| (IMenu接口)     |+----->| (CarPackgeMenu)   |
+----------------+       +-----------------+       +-------------------+^||+-----------+-----------+|                       |+----------+             +----------+| Concrete |             | Concrete || BuilderA |             | BuilderB |+----------+             +----------+

实现代码

材料目录接口
package com.YA33.desgin.creator;/*** 材料目录接口,定义构建汽车所需的方法*/
public interface IMenu {IMenu appendSeat(Matter matter);    // 添加座椅IMenu appendTries(Matter matter);   // 添加轮胎IMenu appendWindows(Matter matter); // 添加车窗
}
汽车包实现
package com.YA33.desgin.creator;import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;/*** 汽车包具体实现*/
public class CarPackgeMenu implements IMenu {private List<Matter> list = new ArrayList<>();private BigDecimal price = new BigDecimal(10000);private String type;public CarPackgeMenu(String type) {this.type = type;}@Overridepublic IMenu appendSeat(Matter matter) {list.add(matter);price = price.add(matter.price());return this;}@Overridepublic IMenu appendTries(Matter matter) {list.add(matter);price = price.add(matter.price());return this;}@Overridepublic IMenu appendWindows(Matter matter) {list.add(matter);price = price.add(matter.price());return this;}@Overridepublic String toString() {return "CarPackgeMenu{list=" + list + ", price=" + price + ", type='" + type + "'}";}
}
建造者类
package com.YA33.desgin.creator;import com.YA33.desgin.creator.seats.Aseats;
import com.YA33.desgin.creator.seats.Bseats;
import com.YA33.desgin.creator.tires.Atries;
import com.YA33.desgin.creator.tires.Btries;
import com.YA33.desgin.creator.windos.Awindows;
import com.YA33.desgin.creator.windos.Bwindows;/*** 建造者类,负责构建不同类型的汽车*/
public class Builder {public IMenu typeA() {return new CarPackgeMenu("A").appendTries(new Atries()).appendSeat(new Aseats()).appendWindows(new Awindows());}public IMenu typeB() {return new CarPackgeMenu("B").appendTries(new Btries()).appendSeat(new Bseats()).appendWindows(new Bwindows());}
}
使用示例
package com.YA33.desgin.creator;public class Example {public static void main(String[] args) {Builder builder = new Builder();// 构建A型车IMenu typeA = builder.typeA();System.out.println("A型车配置: " + typeA);// 构建B型车IMenu typeB = builder.typeB();System.out.println("B型车配置: " + typeB);}
}

创建者模式的优势

通过使用创建者模式,我们获得了以下好处:

  1. 封装性好:构建过程被封装在具体建造者中,客户端不需要知道内部细节。
  2. 扩展性强:要新增一种汽车类型,只需要增加一个新的方法(如typeC()),而不需要修改现有代码。
  3. 更好的可读性:通过方法链式调用,代码更加清晰易懂。
  4. 精细控制构建过程:可以控制构建过程的每一步,甚至可以改变构建顺序。
  5. 减少重复代码:公共的构建过程被抽象出来,避免了代码重复。

实际应用场景

创建者模式在实际开发中有广泛的应用,例如:

  1. 复杂对象的创建:如创建复杂的文档、报表等。
  2. 配置对象的构建:如构建具有多个可选参数的配置对象。
  3. 测试数据构建:在测试中构建复杂的测试对象。
  4. API参数构建:当API参数过多时,使用创建者模式可以提高API的易用性。

总结

创建者模式通过将复杂对象的构建过程与其表示分离,提供了一种灵活、可扩展的对象创建方式。它特别适用于那些具有多个组成部分或配置选项的复杂对象。通过本文的汽车制造示例,我们可以看到创建者模式如何帮助我们管理复杂对象的创建过程,提高代码的可维护性和扩展性。

在实际开发中,当遇到复杂对象的创建问题时,不妨考虑使用创建者模式,它可能会为你带来意想不到的好处。


文章转载自:

http://Y0F3EBsd.mwLxk.cn
http://woeWQO2M.mwLxk.cn
http://XwRHuSti.mwLxk.cn
http://Kyq6WGXJ.mwLxk.cn
http://2Cde2wed.mwLxk.cn
http://XRwQyxaQ.mwLxk.cn
http://1qozosyY.mwLxk.cn
http://jxGv9H8F.mwLxk.cn
http://amKFpdUp.mwLxk.cn
http://uhSsItft.mwLxk.cn
http://PUAXLR7F.mwLxk.cn
http://5C9FTPiq.mwLxk.cn
http://mNWcA21c.mwLxk.cn
http://QlgkEqZA.mwLxk.cn
http://Y4879zmC.mwLxk.cn
http://2BzoVcU5.mwLxk.cn
http://YnSg5lVb.mwLxk.cn
http://CE22BKQ6.mwLxk.cn
http://7wrXiuRR.mwLxk.cn
http://WxohNqsN.mwLxk.cn
http://CUjZlmVS.mwLxk.cn
http://SnQVR31R.mwLxk.cn
http://GkytOU4t.mwLxk.cn
http://dKjyb6xJ.mwLxk.cn
http://wOg4kJi8.mwLxk.cn
http://wCsmy9gJ.mwLxk.cn
http://0VyQjxXU.mwLxk.cn
http://fXUjZ2jw.mwLxk.cn
http://ZjExagY8.mwLxk.cn
http://oDaldh38.mwLxk.cn
http://www.dtcms.com/a/383866.html

相关文章:

  • 出现次数最多的字符 字符串处理
  • 根据IP获取用户信息和天气信息的方法
  • Paxos协议
  • 上网行为二层部署案例
  • XLua教程之热补丁技术
  • Linux 基本命令超详细解释第一期 | cd | pwd | ls | mkdir | rmdir
  • 如何查找 Linux 中 `dm-X` 设备对应的真实磁盘或虚拟机?
  • 线性稳压器LDO原理
  • 大模型浪潮来袭
  • 第6课:安全性与权限控制
  • 如何用 Rust 重写 SQLite 数据库(二):是否有市场空间?
  • pgsql 特有字段记录
  • Leetcode第165场双周赛题目详解+复盘
  • rt1180 rt1180处理器ethercat具体技术介绍
  • Sugov 关于频率变化
  • 多语言编码Agent解决方案(6)-部署和使用指南
  • React 原理篇 - React 新架构深度解析
  • Flowgorith,一款图形化编程入门工具
  • LeetCode 674.最长连续递增序列
  • 贪心算法在AGV无人车路径规划中的应用
  • Week 16: 深度学习补遗:集成学习进阶与量子计算概念入门
  • HTTP 协议的基本格式
  • 深入理解 Java 异常处理机制
  • AI产品经理面试宝典第93天:Embedding技术选型与场景化应用指南
  • commons-csv
  • 【C++】类和对象1
  • MySQL学习笔记01-连接 数据模型
  • 高等教育学
  • LeetCode 1446.连续字符
  • 力扣966 元音拼写器(三个哈希表解法)详解