秒懂设计模式--学习笔记(6)【创建篇-建造者模式】

news2024/9/21 1:40:30

目录

      • 5、建造者模式
          • 5.1 介绍
          • 5.2 建造步骤的重要性
          • 5.3 地产开发商的困惑
          • 5.4 建筑施工方
          • 5.5 工程总监
          • 5.6 项目实施
          • 5.7 建造者模式的各角色定义
          • 5.8 建造者模式

5、建造者模式

5.1 介绍
  • 建造者模式(Builder)又称为生成器模式,主要用于对复杂对象的构建、初始化
    • 它可以将多个简单的组件对象按顺序一步步组装起来,最终构建成一个复杂的成品对象
  • 所构建的对象一定是庞大而复杂的,并且一定是按照既定的制造工序将组件组装起来的。我们通常将负责构建这些大型对象的工程师称为建造者
  • 建造者模式的主要目的在于把烦琐的构建过程从不同对象中抽离出来,使其脱离并独立于产品类与工厂类
    • 最终实现用同一套标准的制造工序能够产出不同的产品
  • 测试类文件
    建造者模式测试类文件
5.2 建造步骤的重要性
  • 建造者面对着什么样的产品模型
    • 玩家选定角色后需要对其进行初始化,假设整个过程分3个步骤完成
      • 第一步,玩家需要为角色选择形象以及分配力量、灵力、体力、敏捷等属性值
      • 第二步,玩家可以为角色配备不同的衣服或铠甲,低于所需力量值的铠甲则不能穿戴;
      • 第三步,玩家选择手持的武器与盾牌,它同上一步一样需要满足一定的条件
    • 成型的游戏角色是依靠角色对象、装备对象组装而成的,对于这种复杂对象的构建一定要依赖建造者来完成
    • 建造者的制造过程不仅要分步完成,还要按照顺序进行
  • 建造者的各制造步骤与逻辑都应该被抽离出来独立于数据模型
  • 复杂的游戏角色设定还需交给专业的建造团队去完成
5.3 地产开发商的困惑
  • 严谨的设计与施工流程的把控
  • 建筑物本身应该由多个组件组成,且各组件按一定工序建造,缺一不可
  • 为了简化其数据模型,我们将组成建筑物的模块归纳为3个组件,分别是地基、墙体、屋顶,将它们组装起来就能形成一座建筑物
    • 以List承载各组件,模拟复杂对象中各组件的顺序组装
    • 分别定义各组件对应的建造方法
    • 用字符串对象String来模拟各个组件对象
    • 重写了toString()方法,按从大到小的组件索引顺序组装各组件,后组装的组件应先展示出来,如屋顶应该首先输出
package builder.entity;

import java.util.ArrayList;
import java.util.List;

/**
 * 数据模型-建筑物类
 **/
public class Building {

    /**
     * 用list来模拟建筑物组件的组装
     *      以List承载各组件,模拟复杂对象中各组件的顺序组装
     */
    private List<String> buildingComponents = new ArrayList<>();


    // 地基
    public void setBasement(String basement) {
        this.buildingComponents.add(basement);
    }

    // 墙体
    public void setWall(String wall) {
        this.buildingComponents.add(wall);
    }

    // 屋顶
    public void setRoof(String roof) {
        this.buildingComponents.add(roof);
    }


    /**
     * 重写了toString()
     *      按从大到小的组件索引【顺序】组装各组件,后组装的组件应先展示出来,如屋顶应该首先输出
     * @return
     */
    @Override
    public String toString() {
        String buildingStr = "";
        for (int i = buildingComponents.size() -1; i >= 0; i--) {
            buildingStr += buildingComponents.get(i);
        }

        return buildingStr;
    }
}

  • 下一步思考
    • 怎样才能用这个复杂的类构建出一个房子对象呢?
    • 首先应该调用哪个建造方法才能保证正确的建造工序,而不至于屋顶在下面,地基却跑到天上去呢
    • 地基、墙体、屋顶,这些组件都去哪里找,如何建造
5.4 建筑施工方
  • 开发商规定施工方都应该至少具备三大组件的建造能力,于是施工标准公布
    • 施工方接口Builder:规定了3个施工标准, 具备三大组件的建造能力
    • 别墅施工方类HouseBuilder
    • 多层公寓施工方类ApartmentBuilder
package builder;

import builder.entity.Building;

/**
 * 施工方接口: 规定了3个施工标准, 具备三大组件的建造能力
 *         建造地基
 *         建造墙体
 *         建造屋顶
 *         获取建筑物,以供产品的交付
 **/
public interface Builder {

    /**
     * 建造地基
     */
    public void buildBasement();

    /**
     * 建造墙体
     */
    public void buildWall();

    /**
     * 建造屋顶
     */
    public void buildRoof();

    /**
     *  获取建筑物,以供产品的交付
     * @return
     */
    public Building getBuilding();
}

package builder.impl;

import builder.Builder;
import entity.Building;

/**
 *  别墅施工方类
 **/
public class HouseBuilder implements Builder {

    private Building house;

    public HouseBuilder() {
        house = new Building();
    }

    @Override
    public void buildBasement() {
        System.out.println("挖土方,部署管道、线缆,水泥加固,搭建围墙、花园。");
        house.setBasement("╬╬╬╬╬╬╬╬\n");
    }

    @Override
    public void buildWall() {
        System.out.println("搭建木质框架,石膏板封墙并粉饰内外墙。");
        house.setWall("|田|田 田|\n");
    }

    @Override
    public void buildRoof() {
        System.out.println("建造木质屋顶、阁楼,安装烟囱,做好防水。");
        house.setRoof("╱◥███◣\n");
    }

    @Override
    public Building getBuilding() {
        return house;
    }
}

package builder.impl;

import builder.Builder;
import builder.entity.Building;

/**
 * 多层公寓施工方类
 **/
public class ApartmentBuilder implements Builder {

    private Building apartment;

    public ApartmentBuilder() {
        apartment = new Building();
    }

    @Override
    public void buildBasement() {
        System.out.println("深挖地基,修建地下车库,部署管道、线缆、风道。");
        apartment.setBasement("╚═══════════╝\n");
    }

    @Override
    public void buildWall() {
        System.out.println("搭建多层建筑框架,建造电梯井,钢筋混凝土浇灌。");
        // 此处假设固定8层
        for (int i = 0; i < 8; i++) {
            apartment.setWall("║ □ □ □ □ ║\n");
       }
    }

    @Override
    public void buildRoof() {
        System.out.println("封顶,部署通风井,做防水层,保温层。");
        apartment.setRoof("╔═══════════╗\n");
    }

    @Override
    public Building getBuilding() {
        return apartment;
    }
}

5.5 工程总监
  • 工程总监类Director: 指导施工,并把控整个施工流程
package builder;

import builder.entity.Building;

/**
 * 工程总监类: 指导施工,并把控整个施工流程
 **/
public class Director {
    private Builder builder;

    public Director(Builder builder) {
        this.builder = builder;
    }

    public void setBuilder(Builder builder) {
        this.builder = builder;
    }

    public Building direct() {
        System.out.println("=====工程项目启动=====");
        // 第一步,打好地基
        builder.buildBasement();
        // 第二步,建造框架、墙体
        builder.buildWall();
        // 第三步,封顶
        builder.buildRoof();
        System.out.println("=====工程项目竣工=====");
        return builder.getBuilding();
    }
}
  • 从宏观上管理项目并指导整个施工队的建造流程
    • 依次调用施工方的打地基方法buildBasement()、建造墙体方法buildWall()及建筑物封顶方法buildRoof(),保证了建筑物自下而上的建造工序
    • 施工方是由外部注入的,所以工程总监并不关心是哪个施工方来造房子,更不关心施工方有什么样的建造工艺
    • 但他能保证对施工工序的绝对把控,也就是说,工程总监只控制施工流程
  • 实际应用中的建造流程也许会更加复杂,且组装各个组件的流程有相对【固定】的逻辑,所以可以从施工方的建造方法中抽离出来并固化在director类中
5.6 项目实施
  • 开发商客户端类Client: 组建了别墅施工队并安排给工程总监进行管理
    • 之后调用其指导方法拿到别墅产品
    • 开发商行将工程总监管理的施工队替换为多层公寓施工方
    • 最终拿到一栋八层公寓
package builder;

import builder.impl.ApartmentBuilder;
import builder.impl.HouseBuilder;

/**
 * 开发商客户端类: 组建了别墅施工队并安排=给工程总监进行管理
 **/
public class Client {
    public static void main(String[] args) {
        //组建别墅施工队
        Director director = new Director(new HouseBuilder());
        System.out.println(director.direct());

        //替换施工队,建造公寓
        director.setBuilder(new ApartmentBuilder());
        System.out.println(director.direct());
    }
}
  • 工艺与工序
    • 施工方接口对施工标准的抽象化、标准化使建造者(施工方)的建造质量达到既定要求,且使各建造者的建造“工艺”能够个性化、多态化
    • 工程总监将*工作流程抽离出来独立于建造者,使建造“工序”得到统一把控
5.7 建造者模式的各角色定义
  • Product(产品):复杂的产品类,构建过程相对复杂,需要其他组件组装而成。如:建筑物类Building,需要地基、墙体、屋顶等组件组成。
  • Builder(建造者):建造者接口,定义了构成产品的各个组件的构建标准,通常有多个步骤。如:施工方接口Builder。
  • ConcreteBuilder(建造者实现):具体的建造者实现类,可以有多种实现,负责产品的组装但不包含整体建造逻辑,如:别墅施工方类HouseBuilder与多层公寓施工方类ApartmentBuilder
  • Director(指导者):持有建造者接口引用的指导者类,指导建造者按一定的逻辑进行建造。如:工程总监类Director。
5.8 建造者模式
  • 复杂对象的构建显然需要专业的建造团队
  • 建造标准的确立让产品趋向多样化
  • 建造工序则交由工程总监去全局把控
  • 最终实现通过相同的构建过程生产出不同产品

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

20.呼吸灯:利用PWM控制小灯在相同时间段内的不同占空比

&#xff08;1&#xff09;设计一段代码&#xff0c;实现led灯在一秒内由完全熄灭到完全点亮&#xff0c;在第二秒由完全点亮转为完全熄灭&#xff0c;循环往复。 &#xff08;2&#xff09;Verilog代码&#xff1a; module breath_led(clk,reset_n,led);input clk;input res…

Open3D 计算点云的欧式距离

目录 一、概述 1.1欧式距离定义 1.2作用和用途 二、代码实现 2.1关键函数 2.2完整代码 三、实现效果 3.1原始点云 3.2处理后点云 一、概述 在Open3D中&#xff0c;compute_point_cloud_distance函数用于计算两个点云之间的距离。具体来说&#xff0c;它计算的是源点云…

进程 VS 线程(javaEE篇)

&#x1f341; 个人主页&#xff1a;爱编程的Tom&#x1f4ab; 本篇博文收录专栏&#xff1a;JavaEE初阶&#x1f449; 目前其它专栏&#xff1a;c系列小游戏 c语言系列--万物的开始_ 等 &#x1f389; 欢迎 &#x1f44d;点赞✍评论⭐收藏&#x1f496;三连支…

一.4 处理器读并解释储存在内存中的指令

此刻&#xff0c;hello.c源程序已经被编译系统翻译成了可执行目标文件hello&#xff0c;并被存放在硬盘上。要想在Unix系统上运行该可执行文件&#xff0c;我们将它的文件名输入到称为shell的应用程序中&#xff1a; linux>./hello hello, world linux> shell是一个命令…

YOLOv10改进 | 添加注意力机制篇 | 添加FocusedLinearAttention助力yolov10实现有效涨点(含二次创新PSA机制)

一、本文介绍 本文给大家带来的改进机制是Focused Linear Attention&#xff08;聚焦线性注意力&#xff09;是一种用于视觉Transformer模型的注意力机制(但是其也可以用在我们的YOLO系列当中从而提高检测精度)&#xff0c;旨在提高效率和表现力。其解决了两个在传统线性注意力…

博美犬插画:成都亚恒丰创教育科技有限公司

​博美犬插画&#xff1a;萌动心灵的细腻笔触 在浩瀚的艺术海洋中&#xff0c;有一种艺术形式总能以它独有的温柔与细腻&#xff0c;触动人心最柔软的部分——那便是插画。而当插画遇上博美犬这一萌宠界的明星&#xff0c;便诞生了一幅幅令人爱不释手的作品&#xff0c;成都亚…

云计算【第一阶段(28)】DNS域名解析服务

一、DNS解析的定义与作用 1.1、DNS解析的定义 DNS解析&#xff08;Domain Name System Resolution&#xff09;是互联网服务中的一个核心环节&#xff0c;它负责将用户容易记住的域名转换成网络设备能够识别和使用的IP地址。一般来讲域名比 IP 地址更加的有含义、也更容易记住…

DNS隧道

dnscat2是一个DNS隧道工具&#xff0c;通过DNS协议创建加密的命令和控制通道&#xff0c;它的一大特色就是服务端会有一个命令行控制台&#xff0c;所有的指令都可以在该控制台内完成。包括:文件上传、下载、反弹Shell 目录 Dnscat2安装 解决bundle instal1特别慢问题 客户…

4.动态SQL(if,choose,where,set,trim,foreach遍历)的使用+$和#的区别

文章目录 动态sql一、动态sql1.if条件判断2、choose、when、otherwise3、where标签4、set标签5、trim标签1)替代where标签效果2) 生成set标签效果 6、foreach迭代遍历1)属性 7.SQL标签-提取重用的SQL代码片段8、bind标签9.MyBatis中${}和#{}的区别: 动态sql 一、动态sql 常见…

windows USB 设备驱动开发-USB 等时传输

客户端驱动程序可以生成 USB 请求块 (URB) 以在 USB 设备中向/从常时等量端点传输数据。虽然USB设备一向以非等时传输出名&#xff0c;USB提供的是一种串行数据&#xff0c;而非等时&#xff0c;但是USB仍然设计了等时传输的机制&#xff0c;但根据笔者的经验&#xff0c;等时传…

vue3项目,表单增删改

效果图 ArticleChannel.vue页面代码 <script setup> import {artGetChannelsService ,artDelChannelService} from /api/article.js import { Edit, Delete } from element-plus/icons-vue //调用open方法&#xff0c;ChannelEdit去修改组件内部类容 import ChannelEdit…

Geoserver源码解读六 插件(怎么在开发模式下使用)

系列文章目录 Geoserver源码解读一 环境搭建 Geoserver源码解读二 主入口 Geoserver源码解读三 GeoServerBasePage Geoserver源码解读四 REST服务 Geoserver源码解读五 Catalog Geoserver源码解读六 插件&#xff08;怎么在开发模式下使用&#xff09; 文章目录 系列文…

QT5.12.9 通过MinGW64 / MinGW32 cmake编译Opencv4.5.1

一、安装前准备&#xff1a; 1.安装QT,QT5.12.9官方下载链接&#xff1a;https://download.qt.io/archive/qt/5.12/5.12.9/ QT安装教程&#xff1a;https://blog.csdn.net/Mark_md/article/details/108614209 如果电脑是64位就编译器选择MinGW64&#xff0c;32位就选择MinGW…

自动驾驶---Perception之Occupancy

1 背景 在阐述Occupancy之前&#xff0c;先理解为什么要使用Occupancy&#xff1f; 如果自动驾驶车辆在行驶过程中看到的物体不是数据集的一部分&#xff0c;这个时候容易出现误判。 而在基于激光雷达的系统中&#xff0c;由于检测到点云&#xff0c;可以确定障碍物的存在&…

《Windows API每日一练》8.5 listbox控件

列表框是将一批文本字符串显示在一个具有滚动功能的方框中的控件。通过发送消息到列表框的窗口过程&#xff0c;程序可以添加或删除列表中的字符串。当列表框中的一个项目被选中时&#xff0c;列表框控件便发送 WM_COMMAND消息到其父窗口。然后父窗口确定哪个项目被选中。 本节…

C# 中的Semaphore(信号量)详解与应用

文章目录 1. 信号量是什么&#xff1f;2. C# 中的 Semaphore 类3. 信号量的使用示例3.1 创建信号量3.2使用信号量同步线程 4. 总结 在并发编程中&#xff0c;同步是一种基本的需求。信号量&#xff08;Semaphore&#xff09;是一种常见的同步机制&#xff0c;它用于控制对共享资…

Jhipster实战中遇到的知识点-开发记录

利用Jhipster开发的网站天赋吉星终于上线啦&#xff0c;本文介绍了在开发过程中遇到的各种小的知识点和技巧&#xff0c;绝对干货&#xff0c;供你参考。大家可以直接点击天赋吉星&#xff0c;看到网站效果。 首先介绍一下项目技术选型&#xff0c;JHipster 版本:8.1.0, 项目类…

stm32 USB CDC类虚拟串口初体验

1. 目标 本文介绍CubeMX生成 USB CDC类虚拟串口工程的操作步骤。 2. 配置流程 时钟配置 usb外设需要48M时钟输入 stm32405使用外部时钟源HSE,否则配不出来48M时钟stm32h750内部有一个48M时钟 stm32f405时钟配置 stm32h750时钟配置 Connectivity ->USB_OTG_FS 和 Connect…

windows obdc配置

进入控制面板&#xff1a; 进入管理工具&#xff1a;

MAC在网络结构中的位置:深入解析

MAC在网络结构中的位置&#xff1a;深入解析 在网络通信的世界里&#xff0c;每一层都扮演着至关重要的角色。今天&#xff0c;我们将聚焦于一个经常被提到但可能不太被理解的概念&#xff1a;MAC&#xff08;Media Access Control&#xff0c;媒体访问控制&#xff09;。我们…