建造者模式的学习与使用以及和抽象工厂模式的区别

news2024/11/24 2:42:32

1、建造者模式的学习

  当创建一个复杂对象时,使用建造者模式可以将对象的构建过程和表示分离开来。它允许使用相同的构建过程来创建不同的表示形式。
  建造者模式的主要思想是将一个复杂对象的构建过程分解为一系列简单的步骤,并且使用一个指导者(Director)来逐步指导构建过程。具体的构建过程由一个抽象的建造者(Builder)和具体的建造者(Concrete Builder)来实现。指导者和建造者之间解耦,通过建造者提供的方法来构建对象。

在这里插入图片描述

2、建造者模式的使用

题目:

  假设你正在开发一个汽车制造系统。汽车有多个组件,包括发动机、底盘、车身和内饰等。使用建造者模式来实现一个汽车制造器,该制造器能够根据用户的选择来构建不同类型的汽车。

实现

  定义一个汽车类(Car),包括发动机(engine)、底盘(chassis)、车身(body)和内饰(interior)等属性,并提供相应的设置方法。
  定义一个汽车建造者接口(CarBuilder),包括设置发动机、底盘、车身和内饰等方法,以及获取最终构建的汽车对象的方法。
  实现两个具体的汽车建造者类,分别用于构建高级车型(LuxuryCarBuilder)和普通车型(StandardCarBuilder)的汽车。每个建造者类都实现了 CarBuilder 接口,根据不同车型的要求设置相应的属性。
  定义一个指挥者类(CarManufacturer),用于指导汽车的构建流程。该类包含一个构建器成员变量,可以接受不同的建造者对象,并提供一个构建汽车的方法。
  在客户端代码中,使用建造者模式构建两辆不同类型的汽车,并展示其属性信息。

代码
/**
 * @Author: myf
 * @CreateTime: 2023-05-17  21:16
 * @Description: Car产品
 */
@Data
public class Car {

    private String engine;

    private String chassis;

    private String body;

    private String interior;

    @Override
    public String toString() {
        return "Car is done " +
                "engine='" + engine + '\'' +
                ", chassis='" + chassis + '\'' +
                ", body='" + body + '\'' +
                ", interior='" + interior + '\'';
    }
}
/**
 * @Author: myf
 * @CreateTime: 2023-05-17  21:18
 * @Description: 抽象汽车构建者
 */
public abstract class CarBuilder {
    protected Car car = new Car();

    /**
     * 发动机
     */
    abstract void setEngine();

    /**
     * 底盘
     */
    abstract void setChassis();

    /**
     * 车体
     */
    abstract void setBody();

    /**
     * 内饰
     */
    abstract void setInterior();

    /**
     * 构建汽车对象
     *
     * @return
     */
    Car build() {
        return car;
    }
}
/**
 * @Author: myf
 * @CreateTime: 2023-05-17  21:23
 * @Description: LuxuryCarBuilder 具体的汽车构建者,高级汽车。
 */
public class LuxuryCarBuilder extends CarBuilder {
    
    @Override
    public void setEngine() {
        super.car.setEngine("super engine");
    }

    @Override
    public void setChassis() {
        super.car.setChassis("super chassis");
    }

    @Override
    public void setBody() {
        super.car.setBody("super body");
    }

    @Override
    public void setInterior() {
        super.car.setInterior("super interior");
    }

}
/**
 * @Author: myf
 * @CreateTime: 2023-05-17  21:25
 * @Description: StandardCarBuilder 具体的汽车构建者,普通汽车。
 */
public class StandardCarBuilder extends CarBuilder {
    
    @Override
    void setEngine() {
        super.car.setEngine("standar engine");
    }

    @Override
    void setChassis() {
        super.car.setChassis("chassis");
    }

    @Override
    void setBody() {
        super.car.setBody("body");
    }

    @Override
    void setInterior() {
        super.car.setInterior("interior");
    }
    
}
/**
 * @Author: myf
 * @CreateTime: 2023-05-17  21:26
 * @Description: CarManufacturer 汽车构建的指挥者 
 */
public class CarManufacturer {
    
    public Car build(CarBuilder carBuilder) {
        carBuilder.setBody();
        carBuilder.setChassis();
        carBuilder.setEngine();
        carBuilder.setInterior();
        return carBuilder.build();
    }
}
public class CarClient {

    public static void main(String[] args) {
        CarManufacturer carManufacturer = new CarManufacturer();
        System.out.println(carManufacturer.build(new LuxuryCarBuilder()).toString());

        CarManufacturer standardCarManufacturer = new CarManufacturer();
        System.out.println(standardCarManufacturer.build(new StandardCarBuilder()).toString());
    }
}

  执行结果

Car is done engine='super engine', chassis='super chassis', body='super body', interior='super interior'
Car is done engine='standar engine', chassis='chassis', body='body', interior='interior'
  以上是一个传统型的建造者模式,在这个模式中,我们无法指定车的这些属性的具体值,在简化版的建造者模式中需要我们自己指定具体的属性。下面是简化版的建造者模式(省去了指导者)。
@Getter
public class Car {

    private String engine;

    private String chassis;

    private String body;

    private String interior;

    private Car(Builder builder) {
        this.body = builder.getBody();
        this.chassis = builder.getChassis();
        this.engine = builder.getEngine();
        this.interior = builder.getInterior();
    }


    public static Builder builder() {
        return new Builder();
    }

    @Getter
    public static final class Builder {
        private String engine;

        private String chassis;

        private String body;

        private String interior;


        public Builder engine(String engine) {
            this.engine = engine;
            return this;
        }

        public Builder chassis(String chassis) {
            this.chassis = chassis;
            return this;
        }

        public Builder body(String body) {
            this.body = body;
            return this;
        }

        public Builder interior(String interior) {
            this.interior = interior;
            return this;
        }

        public Car build() {
            return new Car(this);
        }
    }

    @Override
    public String toString() {
        return "Car is done " +
                "engine='" + engine + '\'' +
                ", chassis='" + chassis + '\'' +
                ", body='" + body + '\'' +
                ", interior='" + interior + '\'';
    }
}

  使用

public class CarClinet {

    public static void main(String[] args) {

        System.out.println(
                Car.builder().chassis("chaghgssis").body("body").engine("engine")
                .interior("interior").build()
        );

    }
}

结果

Car is done engine='engine', chassis='chaghgssis', body='body', interior='interior'
  所以当我们需要生产一个产品的属性比较固定可以使用传统建造者模式来实现;当产品的属性不太固定时,就更适合使用简化版建造者模式来实现。

3、和抽象工厂模式的区别

  之前写的抽象工厂模式;抽象工厂模式更关心的是一组产品的生产,而建造者模式关心的是一个复杂产品的属性的构建过程。比如上面是使用了传统的建造者来实现的,下面我们结合抽象工厂模式来实现一下.大家应该就能更清楚区别了。
  抽象的汽车工厂,负责生产一组汽车

public interface CarFactory {

    /**
     * 高级汽车
     *
     * @return
     */
    Car luxuryCar();

    /**
     * 普通汽车
     *
     * @return
     */
    Car standardCar();
}

  具体的汽车生产工厂,在具体的汽车生产的时候就会涉及到汽车的各个属性,在这里我们就用建造者模式来构建汽车的各个属性,和上面的代码结合起来了

public class CarFactoryImpl implements CarFactory{

    @Override
    public Car luxuryCar() {
        CarManufacturer carManufacturer = new CarManufacturer();
        return carManufacturer.build(new LuxuryCarBuilder());
    }

    @Override
    public Car standardCar() {
        CarManufacturer carManufacturer = new CarManufacturer();
        return carManufacturer.build(new StandardCarBuilder());
    }
}

  结果

public class CarClient {

    public static void main(String[] args) {
        CarManufacturer carManufacturer = new CarManufacturer();
        System.out.println(carManufacturer.build(new LuxuryCarBuilder()).toString());

        CarManufacturer standardCarManufacturer = new CarManufacturer();
        System.out.println(standardCarManufacturer.build(new StandardCarBuilder()).toString());


        CarFactory carFactory = new CarFactoryImpl();
        System.out.println(carFactory.luxuryCar());
        System.out.println(carFactory.standardCar());
    }
}
Car is done engine='super engine', chassis='super chassis', body='super body', interior='super interior'
Car is done engine='standar engine', chassis='chassis', body='body', interior='interior'
Car is done engine='super engine', chassis='super chassis', body='super body', interior='super interior'
Car is done engine='standar engine', chassis='chassis', body='body', interior='interior'

  到这里大家应该清楚就建造者模式和抽象工厂模式的区别了吧。建造者模式关心的是一个产品的属性构建过程;抽象工厂模式关心的是一组产品的生产

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

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

相关文章

14届蓝桥杯青少组省赛(中级组)C++_2023.5.14

选择题: 1、设只含根结点的二叉树高度为1,共有62个结点的完全二叉树的高度为?(C) A.4 B.5 C.6 D.7 2、C++中,bool类型的变量占用字节字数为?(A) A.1 B.2 C.3 D.4 3、该程序的输出为?(A) A.127 B.97 C.63 D.126 4、以下关于数组的说法中…

力扣-根据前序和后序遍历构造二叉树(java)

根据前序和后序遍历构造二叉树 leetcode 889 题(中等)解题思路代码演示二叉树专题 leetcode 889 题(中等) 原题链接: https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-postorder-traversal/ 题…

echart实现地图展示

最近做的页面中需要展示省级地图精确到市级且悬浮到地区上时会显示一些信息 然后参考了网址: “绿色金融” - 江西省 - category-work,geo地理坐标,legend,series-map地图,series-scatter散点图,title标题,tooltip提示框,visualMap视觉映射 - makeapie echarts社区…

同心旋转圆弧

效果如图: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-width, i…

Unity新动画系统之动画状态机Animator Controller

1、创建动画状态机文件 &#xff08;1&#xff09;会在创建动画时自动创建 &#xff08;2&#xff09;Create----Animator Controller 2、动画状态机窗口相关 层级&#xff1a;可以在右侧齿轮设置参数大小 3、添加动画 为对象添加动画后会自动添加到状态机中 4、状态切换 …

halcon安装多个版本时,环境变量设置

记录halcon安装多个版本时&#xff0c;环境变量设置的步骤&#xff0c;方便以后查阅。 1.设置4个环境变量 找到电脑系统中的系统变量&#xff08;不同系统位置不一样&#xff09;&#xff0c;如下图&#xff1a; &#xff08;1&#xff09;变量名&#xff1a;HALCONARCH 变量…

49天精通Java,第36天,Java数组、java数组初始化、java数组赋值

目录 一、声明数组二、初始化数组三、访问数组元素四、遍历数组五、数组复制1、基本类型数组复制2、Object数组复制3、多维数组复制4、对象数组复制 大家好&#xff0c;我是哪吒。 &#x1f3c6;本文收录于&#xff0c;49天精通Java从入门到就业。 全网最细Java零基础手把手入…

企业开发前端框架2023最新前沿技术vue3+vite+vuetify+js+Tailwind Css

文章目录 前言创建项目1、打开vuetify的官网下载项目2、下载依赖3、添加tailwindcss依赖 结束 前言 最近需要开发新的项目&#xff0c;正好学习了Tailwindcss&#xff0c;所以就想着集成到新项目里来&#xff0c;一来可以精进项目经验&#xff0c;也可以感受一下tailwindcss的…

6.1黄金探底回升是否到顶,今日多空如何布局

近期有哪些消息面影响黄金走势&#xff1f;今日黄金多空该如何研判&#xff1f; ​黄金消息面解析&#xff1a;周三(5月31日)黄金期货价格攀升&#xff0c;美国国债收益率下降推动金价升至一周最高收盘位。美市尾盘&#xff0c;现货黄金收报1962.42美元/盎司&#xff0c;上升3…

实验篇(7.2) 05. SSL - 通过浏览器访问远端内网服务器 ❀ 远程访问

【简介】直接将内网服务器映射成公网IP&#xff0c;可以方便的从任何地方访问服务器的指定端口&#xff0c;但是这种方式下&#xff0c;服务器是公开且暴露的。那有没有即方便、又比较安全的远程访问服务器的方法呢&#xff1f;我们来看看SSL VPN的Web模式。 SSL VPN介绍 从概念…

小心618的iPhone优惠套路 实测对比京东更靠谱

今年的618&#xff0c;各大电商平台都纷纷摩拳擦掌&#xff0c;宣称要拿出史上最大力度来承办这次大促活动&#xff0c;希望以最大的诚意来挖掘消费者的需求潜力&#xff0c;作为资深果粉的我&#xff0c;必然也是希望能在此次618大促中买到心仪已久的Apple产品。 对比之后才发…

opencv的Mat相关操作

cv Mat类型的使用 下载安装好opencv&#xff0c;使用时只需添加如下头文件&#xff1a; #include<opencv2/opencv.hpp>另外在工程的属性页中要添加opencv的包含目录与库目录&#xff1a; 在写稍大一些工程的时候&#xff0c;尽量不要直接用using namespace cv; 因为在…

运营策略:影响内容病毒式传播的 8 个维度

目录 01 第一个影响要素就是内容的类型 02 第二个要素时内容的长度 03 第三个要素是要唤起正确的情感 04 第四个是利用趋势&#xff0c;也就是热点问题或事件 05 第五个是视觉效果 06 第六个是增加作者署 07 第七个是在正确的时间发布内容 08 第八个是影响者的力量 病毒…

“实时数据同步:构建高效的 MySQL 数据同步方案“

方案一 基于LVM快照进行备份切换 介绍: MySQL数据库本身并不支持快照功能(sqlServer支持) 因此快照备份是指通过文件系统支持的快照功能对数据库进行备份 备份的前提是将所有数据库文件放在同一文件分区中&#xff0c;然后对该分区进行快照操作 LVM是LINUX系统下对磁盘分区进…

Linux:磁盘资源耗尽故障

有两种经典原因 磁盘空间已被大量的数据占满&#xff0c;空间耗尽。 解决办法&#xff1a;将没有用的大型文件转移或删除 文件i节点耗尽故障 &#xff08;文件过多&#xff09; 解决办法&#xff1a;删除 磁盘被大型文件占满 模拟 准备了一个2G大小的分区 然后进行挂载 我…

电子企业如何高效地使用MES生产管理系统

引言&#xff1a; 在当今数字化、智能化的时代&#xff0c;电子企业的发展已经达到了一个新的高度。与此同时&#xff0c;MES生产管理系统在电子企业中扮演着越来越重要的角色。本文将探讨电子企业如何高效地使用MES生产管理系统&#xff0c;提高企业生产效率和管理水平&#…

基于点云和图像的目标识别与定位,以及目标去重

【背景介绍】 无人系统常常面临对特定目标进行跟踪侦察的任务需求&#xff0c;这就要求无人系统要具备对目标进行识别以及对目标进行定位的能力&#xff0c;同时&#xff0c;任务一般发生在一段连续时间跨度&#xff0c;而相同目标存在被单个机器人重复发现&#xff0c;或者被…

Vue电商项目--详情页面完成

放大镜操作上 <script> var mySwiper new Swiper (.swiper, {direction: vertical, // 垂直切换选项loop: true, // 循环模式选项// 如果需要分页器pagination: {el: .swiper-pagination,},// 如果需要前进后退按钮navigation: {nextEl: .swiper-button-next,pr…

14.2:派对的最大快乐值

派对的最大快乐值 员工信息的定义如下: class Employee { public int happy; // 这名员工可以带来的快乐值 List subordinates; // 这名员工有哪些直接下级 } 公司的每个员工都符合 Employee 类的描述。整个公司的人员结构可以看作是一棵标准的、 没有环的多叉树 树的头节点是公…

框架解耦神器 -- REventBus

REventBus背景 在实际的项目开发中&#xff0c;经常会遇到业务与业务&#xff0c;组件与组件&#xff0c;业务与组件之间的通信&#xff0c;举个例子&#xff1a;当有烟雾传感器检测到烟雾超标时&#xff0c;需要打开排气扇排气&#xff0c;同时显示烟雾浓度显示到显示器中&am…