建造者模式深入理解:演示建造单个和多个产品的实践,结合模板模式,通俗易懂

这篇具有很好参考价值的文章主要介绍了建造者模式深入理解:演示建造单个和多个产品的实践,结合模板模式,通俗易懂。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

首先呢看下建造者的定义是什么样的,先读一遍

建造者模式

建造者模式(Builder Pattern)是一种创建型设计模式,它主要用于将一个复杂对象的构建过程与它的表示分离,使得同样的构建过程可以创建不同的表现形式。这种模式通过一系列可重用的独立的类(称为建造者或构建器)来一步一步创建一个复杂的对象,而不需要知道具体的内部构造细节

优缺点

建造者模式的主要优点

  1. 封装性好:通过建造者将产品的各个部件和组装过程封装起来,客户端无需了解产品内部的具体构造细节,只需指定需要的产品类型和配置即可。
  2. 扩展性好:由于每个具体建造者都是相互独立的,因此新增一种产品或者变更已有产品的构建方式时,只需要新增或修改相应的建造者类,不影响其他部分代码,从而实现系统的松耦合。
  3. 便于控制构建过程:在构建过程中,可以根据需要逐步细化构造步骤,灵活地控制产品的创建过程,甚至支持动态决定构建部件的数量和顺序。
  4. 便于并行构造:在某些场景下,不同部分的构建可以独立进行,有利于提高系统性能,特别是在多线程环境下的构建。

建造者模式的主要缺点

  1. 增加类的数量:引入建造者模式会增加额外的类,包括抽象建造者、具体建造者和可能的导演类等,增加了系统的复杂性和理解难度。
  2. 内部修改困难:一旦产品结构较为复杂,对于产品内部细节的改动可能会导致多个建造者的相关逻辑都需要调整,维护成本相对较高。
  3. 过度设计风险:如果对象结构比较简单,或者变化不多,使用建造者模式可能会显得过于复杂,不适用于简单对象的构建。
    总结来说,建造者模式非常适合用于创建具有多重构造参数或组合选项的复杂对象,尤其当这些选项的不同组合可能导致大量微小差异的产品实例时,该模式能够很好地管理和组织这些复杂性。

网图来一张
建造者模式深入理解:演示建造单个和多个产品的实践,结合模板模式,通俗易懂,【设计模式及应用】,建造者模式,java,设计模式,高级设计,后端,设计
好了,直接上代码,这里我们先构建一个CarProduct,很多描述都写在了对应的注释中了啊,这里就不过多赘述

package com.mtgg.laoxiang.service.example.designer.builder;

import lombok.Data;

/**
 * 要构建的产品对象
 */
@Data
public class CarProduct {
    private String partA;
    private String partB;
    private String partC;
}
package com.mtgg.laoxiang.service.example.designer.builder;

/**
 * 建造者抽象类
 */
public abstract class Builder {
    //建造产品时,实例化,相当于统一放到一个地方,product相当于一个封装,里面可以放各种东西的组成
    protected CarProduct carProduct = new CarProduct();


    //建造,建造各种东西然后set到product中
    public abstract void builderPartA();

    public abstract void builderPartB();

    public abstract void builderPartC();

    //提供获得产品的入口,要获得这个产品,就调用这个方法
    public CarProduct getResult() {
        return carProduct;
    }

}

上面定义了产品,构造器,获取产品的方法,下面这个就是构造器要具体干的活了

package com.mtgg.laoxiang.service.example.designer.builder;

public class BJBuilder extends Builder{

    @Override
    public void builderPartA() {
        System.out.println("构建个1球");
        carProduct.setPartA("1球");
    }

    @Override
    public void builderPartB() {
        System.out.println("构建个2球");
        carProduct.setPartB("2球");
    }

    @Override
    public void builderPartC() {
        System.out.println("构建个3球");
        carProduct.setPartC("3球");
    }
}

package com.mtgg.laoxiang.service.example.designer.builder;

public class HZBuilder extends Builder{

    @Override
    public void builderPartA() {
        System.out.println("构建个1香蕉");
        carProduct.setPartA("1香蕉");
    }

    @Override
    public void builderPartB() {
        System.out.println("构建个2香蕉");
        carProduct.setPartB("2香蕉");
    }

    @Override
    public void builderPartC() {
        System.out.println("构建个3香蕉");
        carProduct.setPartC("3香蕉");
    }
}

指挥者来了,指挥我到底想要啥,什么数量,什么顺序,定义几个图纸来交给构造器去构造,然后main使用的时候直接调用这个定义好的流程,就能拿到对应的产品

package com.mtgg.laoxiang.service.example.designer.builder;

/**
 * 指挥者
 * 控制生成流程
 */
public class Director {
    //这个抽象类可以定义成全局变量,也可以定义接口,此处可以引用接口,更不违反原则
    private Builder builder;

    /**
     * 注入builder
     */
    private Director(Builder builder) {
        this.builder = builder;
    }

    /**
     * 控制流程,此处类似使用模板模式
     */
    public CarProduct construct2(){
        builder.builderPartC();
        builder.builderPartA();
        return builder.getResult();
    }

    public CarProduct construct(){
        builder.builderPartB();
        builder.builderPartA();
        builder.builderPartC();
        return builder.getResult();
    }

    public static void main(String[] args) {
        //此处可选择不同的建造者建造产品
        Director director = new Director(new HZBuilder());
        CarProduct construct = director.construct();
        System.out.println(construct);

        director = new Director(new BJBuilder());
        CarProduct construct1 = director.construct2();
        System.out.println(construct1);
    }

}

*构建个2香蕉
构建个1香蕉
构建个3香蕉
Product(partA=1香蕉, partB=2香蕉, partC=3香蕉)
构建个3球
构建个1球
Product(partA=1球, partB=null, partC=3球) *

建造者模式深入理解:演示建造单个和多个产品的实践,结合模板模式,通俗易懂,【设计模式及应用】,建造者模式,java,设计模式,高级设计,后端,设计

如果我想建造另外一个对象呢?难道类似的类都要加一份?那肯定是low的,做法如下,

可以加具体建造,定义好要建造的东西,再建一个指挥者方法,尽量不要在原来的方法上改,改造后如下

假如有另一个对象PhoneProduct

@Data
public class PhoneProduct {
    private String pa;
    private String pb;
    private String pc;
}

Builder中加上要构建的这个产品,并加个返回产品的方法,所以这么看的话那几个构建的抽象方法就不能太个性化,最好抽象一些,像是定义三四个工厂一样,具体怎么生产看子类实现

public abstract class Builder {
    //建造产品时,实例化,相当于统一放到一个地方,product相当于一个封装,里面可以放各种东西的组成

    //另外一个产品
    protected PhoneProduct phoneProduct = new PhoneProduct();
……………………

    public PhoneProduct getPhoneResult() {
        return phoneProduct;
    }
}

好了我们定义一个子类去构建具体的内容,不用改另外一个对象的构建,保证对扩展开放,对修改关闭

public class XMBuilder extends Builder{
    @Override
    public void builderPartA() {
        System.out.println("小米a");
        phoneProduct.setPa("pa");
    }

    @Override
    public void builderPartB() {
        System.out.println("小米b");
        phoneProduct.setPb("pb");
    }

    @Override
    public void builderPartC() {
        System.out.println("小米c");
        phoneProduct.setPc("pc");
    }
}

指挥者我们改造一下,构建顺序以及数量都可以抽出来共用,只需要定义construct2或constructPhone方法,指定模板,返回产品就OK了,想要啥产品要啥产品

public class Director {
    //这个抽象类可以定义成全局变量,也可以定义接口,此处可以引用接口,更不违反原则
    private Builder builder;

    /**
     * 注入builder
     */
    private Director(Builder builder) {
        this.builder = builder;
    }

    /**
     * 构建模板 定义构建顺序以及内容
     */
    public void buildTemplateA(){
        builder.builderPartB();
        builder.builderPartA();
        builder.builderPartC();
    }

    /**
     * 构建模板 定义构建顺序以及内容
     */
    public void buildTemplateB(){
        builder.builderPartC();
        builder.builderPartA();
    }

    /**
     * 构建以及获取car产品的入口
     */
    public CarProduct construct2(){
        this.buildTemplateB();
        return builder.getResult();
    }

	//不同形态的car产品
    public CarProduct construct(){
        this.buildTemplateA();
        return builder.getResult();
    }

	//这个是构建和获取phone产品的入口
    public PhoneProduct constructPhone(){
        this.buildTemplateA();
        return builder.getPhoneResult();
    }

    public static void main(String[] args) {
        //此处可选择不同的建造者建造产品
        Director director = new Director(new HZBuilder());
        CarProduct construct = director.construct();
        System.out.println(construct);

        director = new Director(new BJBuilder());
        CarProduct construct1 = director.construct2();
        System.out.println(construct1);

        //构建另外一个产品,使用时指定用XMBuilder这个厂家生产的就行
        director = new Director(new XMBuilder());
        PhoneProduct construct2 = director.constructPhone();
        System.out.println(construct2);
    }

}

下面这是执行结果

构建个2香蕉
构建个1香蕉
构建个3香蕉
CarProduct(partA=1香蕉, partB=2香蕉, partC=3香蕉)
构建个3球
构建个1球
CarProduct(partA=1球, partB=null, partC=3球)
小米b
小米a
小米c
PhoneProduct(pa=pa, pb=pb, pc=pc)

祝你好运!~~文章来源地址https://www.toymoban.com/news/detail-816021.html

到了这里,关于建造者模式深入理解:演示建造单个和多个产品的实践,结合模板模式,通俗易懂的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 深入理解中文编码:原理、应用与实践

    编码是将信息转换为特定格式以便存储、传输或处理的过程。在计算机科学中,编码通常指的是将文本、图像、音频等数据转换为数字形式的过程。编码的作用在于统一数据格式、提高数据传输效率、确保数据安全性等方面发挥着重要作用。 中文编码相较于英文等西方语言编

    2024年04月12日
    浏览(47)
  • 深入理解JavaScript闭包:从概念到实践

    JavaScript是一门强大且灵活的编程语言,而闭包(Closure)则是JavaScript中一个非常重要且常用的概念。虽然闭包在JavaScript开发中经常被提及,但它的概念和工作原理可能对一些开发者来说仍然有些模糊。本篇博客旨在帮助读者深入理解JavaScript闭包,从概念到实践,让您能够充

    2024年02月16日
    浏览(45)
  • 深入理解 Kafka 集群管理与最佳实践

    构建和管理一个稳定、高性能的Kafka集群对于实现可靠的消息传递至关重要。本文将深入研究Kafka集群的各个方面,包括集群搭建、节点配置、分区与副本管理、安全性与监控,为读者提供全面的指导和实例代码。 1.1 Broker 节点 在Kafka集群中,Broker节点是核心组件,负责消息的

    2024年02月03日
    浏览(58)
  • 深入理解Kafka:架构、设计原则及最佳实践

    Kafka是一款由Apache开发的分布式流处理平台,它最初是由LinkedIn公司在2010年开发的。从最初的消息队列到如今的分布式流处理平台Kafka经历了一个逐步演化的过程。 Kafka最开始的设计目的是解决LinkedIn内部存在的海量数据传输问题,在其不断的发展中Kafka逐渐发展成为一种可持

    2024年02月07日
    浏览(60)
  • 【深入理解设计模式】 工厂设计模式

    工厂设计模式是一种 创建型设计模式 ,它提供了一种在不指定具体类的情况下创建对象的接口。在工厂设计模式中,我们定义一个创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。 工厂设计模式的目的是: 封装对象创建的过程,使得

    2024年02月22日
    浏览(45)
  • 深入理解MVVM架构模式

    原文合集地址如下,有需要的朋友可以关注 本文地址 MVVM是一种用于构建用户界面的软件架构模式,它的名称代表着三个组成部分:Model(模型)、View(视图)和ViewModel(视图模型)。MVVM的主要目标是将应用程序的UI与其底层数据模型分离,通过数据绑定实现数据和UI的自动

    2024年02月12日
    浏览(33)
  • 深入理解Java虚拟机:JVM高级特性与最佳实践

    Java虚拟机 Java虚拟机(Java Virtual Machine,JVM)是Java语言的核心,是执行Java二进制代码的虚拟计算机。 JVM本身是一个进程,负责解析Java程序并将其转换为特定平台可以执行的指令集。 通过JVM,Java程序可以实现“一次编写,到处运行”的特性,使Java具有很强的平台无关特性。

    2024年02月07日
    浏览(52)
  • 深入理解设计模式-创建型之单例模式

    如果有些数据在系统中应该且只能保存一份,那就应该设计为单例类。 如:配置类:在系统中,我们只有一个配置文件,当配置文件被加载到内存之后,应该被映射为一个唯一的【配置实例】,此时就可以使用单例,当然也可以不用。 全局计数器:我们使用一个全局的计数

    2024年02月12日
    浏览(57)
  • 《C++ Core Guidelines解析》:深入理解C++的最佳实践

    在计算机编程领域,C++一直以其高效、灵活和强大而闻名。然而,C++作为一种复杂的编程语言,如果没有正确的理解和使用,很容易导致软件质量的下降和性能问题的出现。幸运的是,一本名为《C++Core Guidelines解析》的书籍为C++开发者提供了一个宝贵的指南,以帮助他们更好

    2024年02月09日
    浏览(51)
  • 【Java基础】深入理解反射、反射的应用(工厂模式、代理模式)

    Java 反射机制是指在 运行时动态地获取和操作类的信息、调用对象的方法和访问对象的属性的能力 。通过反射,可以在程序运行时分析和修改类的结构、行为和状态。 Java 反射机制提供了以下功能: 获取类的信息:可以获取类的名称、修饰符、父类、实现的接口等。 创建对

    2024年02月09日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包