设计模式——建造者(Builder)模式

建造者模式(Builder Pattern),又叫生成器模式,是一种对象构建模式 它可以将复杂对象的建造过程抽象出来,使这个抽象过程的不同实现方法可以构造出不同表现的对象。建造者模式是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可 以构建它们,用户不需要知道内部的具体构建细节。

简单来说,建造者模式允许你按步骤创建复杂的对象,同时将对象的构建与其表示分离。

主要解决的问题是当创建一个复杂对象时,如果直接在代码中进行对象的创建和初始化,会导致代码变得复杂而难以维护。

而建造者模式通过将对象的构建过程委派给不同的建造者,使得代码更加清晰、可读,并且可以灵活地构建不同的对象表示形式。

当我们需要创建一个对象,但该对象具有复杂的构建过程,并且构建过程可以有不同的表示形式时,可以考虑使用建造者模式。

建造者模式包含4个元素:

  • 抽象建造者(Builder):一个抽象接口,规范了产品对象的各个组成成分的建造。
  • 具体建造者(ConcreteBuilder):与应用程序紧密相关的一些类,它们在应用程序调用下创建产品的实例。
  • 导演者(Director):调用具体建造者角色来创建产品对象。
  • 产品(Product):一般是一个较为复杂的对象。

优点包括:

  1. 将对象的构建过程封装在一个建造者类中,使得客户端代码与具体构建过程解耦,提高了代码的可维护性和可读性。
  2. 可以灵活地构建不同表示形式的对象,通过调整建造者的步骤和配置,可以得到不同的对象。
  3. 可以更好地控制对象的构建过程,避免了在代码中直接创建和初始化对象的复杂性。

缺点包括:

  1. 建造者模式增加了代码的复杂性,因为需要定义多个类来实现构建者和产品对象,可能会增加项目的工程复杂性。
  2. 如果产品的属性发生变化,需要修改构建者类和产品类,可能会引起一定的维护成本。

注意事项:与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。

案例

我们假设一个快餐店的商业案例,其中,一个典型的套餐可以是一个汉堡(Burger)和一杯冷饮(Cold drink)。汉堡(Burger)可以是素食汉堡(Veg Burger)或鸡肉汉堡(Chicken Burger),它们是包在纸盒中。冷饮(Cold drink)可以是可口可乐(coke)或百事可乐(pepsi),它们是装在瓶子中。

我们将创建一个表示食物条目(比如汉堡和冷饮)的 Item 接口和实现 Item 接口的实体类,以及一个表示食物包装的 Packing 接口和实现 Packing 接口的实体类,汉堡是包在纸盒中,冷饮是装在瓶子中。

然后我们创建一个 Meal 类,带有 ItemArrayList 和一个通过结合 Item 来创建不同类型的 Meal 对象的 MealBuilderBuilderPatternDemo 类使用 MealBuilder 来创建一个 Meal

建造者模式的 UML 图

步骤 1

创建一个表示食物条目和食物包装的接口。

public interface Item {public String name();public Packing packing();public float price();    
}

public interface Packing {public String pack();
}

步骤 2

创建实现 Packing 接口的实体类。

public class Wrapper implements Packing {@Overridepublic String pack() {return "Wrapper";}
}
public class Bottle implements Packing {@Overridepublic String pack() {return "Bottle";}
}

步骤 3

创建实现 Item 接口的抽象类,该类提供了默认的功能。

public abstract class Burger implements Item {@Overridepublic Packing packing() {return new Wrapper();}@Overridepublic abstract float price();
}
public abstract class ColdDrink implements Item {@Overridepublic Packing packing() {return new Bottle();}@Overridepublic abstract float price();
}

步骤 4

创建扩展了 Burger 和 ColdDrink 的实体类。

public class VegBurger extends Burger {@Overridepublic float price() {return 25.0f;}@Overridepublic String name() {return "Veg Burger";}
}
public class ChickenBurger extends Burger {@Overridepublic float price() {return 50.5f;}@Overridepublic String name() {return "Chicken Burger";}
}
public class Coke extends ColdDrink {@Overridepublic float price() {return 30.0f;}@Overridepublic String name() {return "Coke";}
}
public class Pepsi extends ColdDrink {@Overridepublic float price() {return 35.0f;}@Overridepublic String name() {return "Pepsi";}
}

步骤 5

创建一个 Meal 类,带有上面定义的 Item 对象。

import java.util.ArrayList;
import java.util.List;public class Meal {private List<Item> items = new ArrayList<Item>();    public void addItem(Item item){items.add(item);}public float getCost(){float cost = 0.0f;for (Item item : items) {cost += item.price();}        return cost;}public void showItems(){for (Item item : items) {System.out.print("Item : "+item.name());System.out.print(", Packing : "+item.packing().pack());System.out.println(", Price : "+item.price());}        }    
}

步骤 6

创建一个 MealBuilder 类,实际的 builder 类负责创建 Meal 对象。

public class MealBuilder {public Meal prepareVegMeal (){Meal meal = new Meal();meal.addItem(new VegBurger());meal.addItem(new Coke());return meal;}   public Meal prepareNonVegMeal (){Meal meal = new Meal();meal.addItem(new ChickenBurger());meal.addItem(new Pepsi());return meal;}
}

步骤 7

BuiderPatternDemo 使用 MealBuilder 来演示建造者模式(Builder Pattern)。

public class BuilderPatternDemo {public static void main(String[] args) {MealBuilder mealBuilder = new MealBuilder();Meal vegMeal = mealBuilder.prepareVegMeal();System.out.println("Veg Meal");vegMeal.showItems();System.out.println("Total Cost: " +vegMeal.getCost());Meal nonVegMeal = mealBuilder.prepareNonVegMeal();System.out.println("\n\nNon-Veg Meal");nonVegMeal.showItems();System.out.println("Total Cost: " +nonVegMeal.getCost());}
}

步骤 8

执行程序,输出结果:

Veg Meal
Item : Veg Burger, Packing : Wrapper, Price : 25.0
Item : Coke, Packing : Bottle, Price : 30.0
Total Cost: 55.0Non-Veg Meal
Item : Chicken Burger, Packing : Wrapper, Price : 50.5
Item : Pepsi, Packing : Bottle, Price : 35.0
Total Cost: 85.5

总结

建造者模式是一种创建型设计模式,用于将复杂对象的构建过程与其表示分离。它通过将复杂对象的构建过程分解为多个简单的步骤来实现。在Java中,我们可以使用建造者模式来创建复杂对象,并且可以根据需要使用不同的建造者来创建不同的表示。建造者模式的优点包括可重用性和易于维护和扩展,但它的缺点是代码结构较为复杂。建造者模式适用于需要创建多个相似对象,或者需要在不同的上下文中创建不同的对象表示的情况。如果需要创建的对象较为简单,可能会使用建造者模式变得过于繁琐。

总之,建造者模式是一种非常有用的设计模式,可以帮助我们更好地管理对象的构建过程,并且使得代码更加易于维护和扩展。如果你需要创建一个复杂的对象,或者需要在不同的上下文中创建不同的对象表示,建议你考虑使用建造者模式来实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/68138.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Bean的作用域和生命周期

文章目录 1. Bean的作用域2. Spring的生命周期3. Bean的生命周期4. 相关注解总结 1. Bean的作用域 Bean 的作用域指的是 Bean 在 Spring 容器中的行为&#xff08;Bean 实例创建及生命周期&#xff09;&#xff0c;它的行为是由 Spring 来管理的&#xff0c;可以根据具体情况选…

Kali Linux助您网络安全攻防实战

Kali Linux&#xff1a;黑客与防御者的神器 Kali Linux是一款专为网络安全测试和攻防实践而设计的操作系统。它汇集了大量的安全工具&#xff0c;可以用于渗透测试、漏洞扫描、密码破解等任务&#xff0c;不仅为黑客提供了强大的攻击能力&#xff0c;也为安全防御者提供了测试和…

【奥义】如何用ChatGPT写论文搞模型

目录 你是否曾经在复现科研论文的结果时感到困难重重&#xff1f; 引言 1 打开需要复现的目标文献 2 提取公式定义的语句 3 文章公式、图实现 &#xff08;1&#xff09;用python复现目标文献中的公式 &#xff08;2&#xff09;用python复现目标文献中的图 4 Copy代码…

重试框架入门:Spring-RetryGuava-Retry

前言 在日常工作中&#xff0c;随着业务日渐庞大&#xff0c;不可避免的涉及到调用远程服务&#xff0c;但是远程服务的健壮性和网络稳定性都是不可控因素&#xff0c;因此&#xff0c;我们需要考虑合适的重试机制去处理这些问题&#xff0c;最基础的方式就是手动重试&#xf…

威海--游记

威海盛夏已至&#xff0c;气温攀升的同时&#xff0c;小伙伴们出去玩的心也都藏不住了。 作为离韩国最近的城市&#xff0c;不出国门就能轻松get到浓浓的“韩范儿”&#xff01;从韩式建筑、小吃甜品&#xff0c;再到各种宝藏打卡小店&#xff0c;玩法超多&#xff0c;好吃好看…

vmagent获取node-exporter配置

vmagent 使用以下命令添加图表 helm 存储库&#xff1a; helm repo add vm https://victoriametrics.github.io/helm-charts/helm repo update 列出vm/victoria-metrics-agent可供安装的图表版本&#xff1a; helm search repo vm/victoria-metrics-agent -l victoria-met…

2023年国赛数学建模思路 - 案例:异常检测

文章目录 赛题思路一、简介 -- 关于异常检测异常检测监督学习 二、异常检测算法2. 箱线图分析3. 基于距离/密度4. 基于划分思想 建模资料 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 一、简介 – 关于异常…

win11如何去掉桌面快捷方式的小箭头(原创)

begin 打开注册表,Windows搜索框里搜 注册表编辑器(register editor),打开.. 找到 接着跟进.. 新建一个项名, Shell Icons 继续.... 值设为29 双击开页面 输入数据 %windir%\System32\shell32.dll,-51 到此,保存,到桌面,小箭头还是没有消失 ctrl shift esc 打开 任务管理…

Redis辅助功能

一、Redis队列 1.1、订阅 subscribe ch1 ch2 1.2 publish:发布消息 publish channel message 1.3 unsubscribe: 退订 channel 1.4 模式匹配 psubscribe ch* 模糊发布&#xff0c;订阅&#xff0c;退订&#xff0c; p* <channelName> 1.5 发布订阅原理 订阅某个频道或…

产品需求管理软件:了解常见选择和功能

产品需求管理软件是一种非常重要的工具。它可以帮助企业更好地理解客户需求&#xff0c;提高产品开发效率并降低成本。本文将介绍一些常见的产品需求管理软件及其主要功能。 “产品需求管理软件有哪些&#xff1f;比较流行的有Zoho Projects、Trello、Asana、Smartsheet等。” …

CHATGPT源码简介与使用指南

CHATGPT源码的基本介绍 CHATGPT源码备受关注&#xff0c;它是一款基于人工智能的聊天机器人&#xff0c;旨在帮助开发者快速搭建自己的聊天机器人&#xff0c;无需编写代码。下面是对CHATGPT搭建源码的详细介绍。 CHATGPT源码的构建和功能 CHATGPT源码是基于Google的自然语言…

解决selenium的“can‘t access dead object”错误

目录 问题描述 原因 解决方法 示例代码 资料获取方法 问题描述 在python执行过程中&#xff0c;提示selenium.common.exceptions.WebDriverException: Message: TypeError: cant access dead object 原因 原因是代码中用到了frame,获取元素前需要切换到frame才能定位到…