c#设计模式-创建型模式 之 建造者模式

news2024/11/28 7:39:22

简介:

        将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。提供了一种创建对象的最佳方式。一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。意图是将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
        建造者模式的核心思想就是将一个复杂对象的构建与其表示分离,让用户只需要关注需要构造的对象的属性即可。这样用户不需要知道对象的内部实现细节,只需要通过Builder提供的接口方法来设置对象属性,就可以得到一个完整的对象。
建造者( Builder )模式包含如下角色:
  1. 抽象建造者类(Builder):这个接口规定要实现复杂对象的那些部分的创建,并不涉及具体的部件对象的创建。
  2. 具体建造者类(ConcreteBuilder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。在构造过程完成后,提供产品的实例。
  3. 产品类(Product):要创建的复杂对象。
  4. 指挥者类(Director):调用具体建造者来创建复杂对象的各个部分,在指导者中不涉及具体产品的信息,只负责保证对象各部分完整创建或按某种顺序创建。

代码演示

我们使用代码来演示一下,使用建造者方式创建自行车

首先创建一个Bike类,给自行车提供三个属性,车篮、架子、座包

public class Bike
{
    public string basket { get; set; }
    public string frame { get; set; }
    public string seat { get; set; }
}

抽象建造者类(Builder

在这里将bike实例化了,还有三个抽象方法,分别构建车篮、架子、座包,因为builder调用具体建造者来创建,具体业务我们在实现类里重写方法。

public abstract class Builder
{
    protected Bike mBike = new Bike();

    public abstract void buildBasket();

    public abstract void buildFrame();

    public abstract void buildSeat();

    public Bike createBike()
    {
        return mBike;
    }
}

具体建造者类(ConcreteBuilder)

这里写了两个实现类,用于创建不同的自行车

//山地自行车
public class MountainBuilder : Builder
{
    public override void buildBasket()
    {
        mBike.basket = "蓝色车篮";
    }

    public override void buildFrame()
    {
        mBike.frame = "铝合金车架";
    }

    public override void buildSeat()
    {
        mBike.seat = "橡胶车座";
    }
}

//公路自行车
public class RoadBuilder : Builder
{
    public override void buildBasket()
    {
        mBike.basket = "黑色车篮";
    }

    public override void buildFrame()
    {
        mBike.frame = "碳纤维车架";
    }

    public override void buildSeat()
    {
        mBike.seat = "海绵车座";
    }
}

指挥者类(Director

负责保证对象各部分完整创建或按某种顺序创建,这里根据传进来的builder实现类,依次调用他们的build方法。

public class Director
{
    private Builder _builder;

    public Director(Builder builder)
    {
        _builder = builder;
    }

    public Bike construct()
    {
        _builder.buildBasket();
        _builder.buildFrame();
        _builder.buildSeat();
        return _builder.createBike();
    }
}

测试一下

创建一个Director实例,参数中带一个公路车实例,调用他的construct方法,就可以得到一辆公路车

    public static void Main(string[] args)
    {
        var director = new Director(new RoadBuilder());
        Bike bike = director.construct();
        Console.WriteLine($"车篮:{bike.basket};  车架:{bike.frame};  车座:{bike.seat}");
    }

如果想换成山地车,只需要将参数换成山地车的实例

var director = new Director(new MountainBuilder());

 

 如果说现在有一个需求,所有使用此建造者模式创建的自行车都需要把自行车去掉,我们只需要在指挥者类Director中去掉对应的创建车篮方法

这时,所有调用指挥者的construct创建的自行车实例都没有车篮了

总结:

优点:
  • 建造者模式的封装性很好。使用建造者模式可以有效的封装变化,在使用建造者模式的场景中,一般产品类和建造者类是比较稳定的,因此,将主要的业务逻辑封装在指挥者类中对整体而言可以取得比较好的稳定性。
  • 在建造者模式中,客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。可以更加精细地控制产品的创建过程 。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也更方便使用程序来控制创建过程。
  •  建造者模式很容易进行扩展。如果有新的需求,通过实现一个新的建造者类就可以完成,基本上不用修改之前已经测试通过的代码,因此也就不会对原有功能引入风险。符合开闭原则。
缺点:
  • 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。
使用场景:
  • 创建的对象较复杂,由多个部件构成,各部件面临着复杂的变化,但构件间的建造顺序是稳定的。
  • 创建复杂对象的算法独立于该对象的组成部分以及它们的装配方式,即产品的构建过程和最终的表示是独立的。

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

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

相关文章

LeetCode_模拟_中等_2596.检查骑士巡视方案

目录 1.题目2.思路3.代码实现(Java) 1.题目 骑士在一张 n x n 的棋盘上巡视。在有效的巡视方案中,骑士会从棋盘的左上角出发,并且访问棋盘上的每个格子恰好一次 。 给你一个 n x n 的整数矩阵 grid ,由范围 [0, n * …

SAP 委外联产品 如何分摊加工费 ?

SAP 委外联产品 如何分摊加工费 ? 目前对委外联产品分摊加工费还没好办法,看上去与委外副产品业务是一样的,除了主数据设置多了一些。 委外物料与联产品物料都设置S价,跑物料分类账时根据主数据设置分摊规则将差异分摊到对应的物…

获取Windows 10中的照片(旧版)下载

Windows 10中的新版照片应用,目前发现无法直接打开部分iOS设备上存储的照片。需要使用照片(旧版)才行。 但目前应用商店中无法直接搜索到照片(旧版),因此笔者提供如下链接,可以直接访问并呼出W…

Swift学习内容精选(二)

Swift 类是构建代码所用的一种通用且灵活的构造体。 我们可以为类定义属性(常量、变量)和方法。 与其他编程语言所不同的是,Swift 并不要求你为自定义类去创建独立的接口和实现文件。你所要做的是在一个单一文件中定义一个类,系…

详解带头双向循环列表

目录 前言 一、带头双向循环链表的结构 二、 带头双向循环链表的实现 2.1链表的创建 2.2开辟新的结点 2.3初始化 2.4释放销毁 2.5链表的打印 2.7尾插 2.8尾删 2.9头插 2.10头删 三、带头双向循环链表中间随机值的插入和删除 3.1在pos位置插入x 3.2删除pos位置的…

C#回调函数学习1

回调函数(Callback Function)是一种函数指针,它指向的是由用户自己定义的回调函数。我们将这个回调函数的指针作为参数传递给另外一个函数,在这个函数工作完成后,它将通过这个回调函数的指针来回调通知调用者处理结果。…

XREAL 联合创始人吴克艰谈AR:下一代计算平台及其关键技术

// 编者按:一种行业观点是,AR或是未来十年、三十年的革命性技术,是下一代计算平台。近半个世纪,我们总能听到苹果在AR行业的创新动作,开辟了新的硬件范式。AR/VR行业为苹果不断欢呼的同时,激发了人们的好…

JAVA设计模式8:装饰模式,动态地将责任附加到对象上,扩展对象的功能

作者主页:Designer 小郑 作者简介:3年JAVA全栈开发经验,专注JAVA技术、系统定制、远程指导,致力于企业数字化转型,CSDN博客专家,阿里云社区专家博主,蓝桥云课讲师。 目录 一、什么是装饰模式二、…

linux安装Sentinal1.8.6

前言: 使用docker search sentinel-dashboard命令,发现docker中的镜像版本过低,由于要配合使用1.8.6,所以这里采用java后台运行sentinel1.8.6-jar的方式。 1、官网下载对应版本jar(https://github.com/alibaba/Sentin…

【Unity编辑器扩展】| 自定义窗口和面板

前言【Unity编辑器扩展】| 自定义窗口和面板一、EditorWindow二、ScriptableWizard三、编辑器绘制3.1 文本输入3.2 空行3.3 滑动条、进度条3.4 枚举选择3.5 其他总结前言 前面我们介绍了Unity中编辑器扩展的一些基本概念及基础知识,还有编辑器扩展中用到的相关特性Attribute介…

招募 AIGC 训练营助教 @上海

诚挚邀请对社区活动感兴趣的你,成为我们近期开展的训练营助教。 与我们共同开启这场创新之旅! 助教需要参与: 协助策划和组织训练营活动 协助招募和筛选学员 协助制定训练营的宣传方案 负责协调和组织各项活动 助教可获得: AIGC知…

vue cli 打包、生产环境http-proxy-middleware代理

结构树 版本 1、创建vue.config.js const path require(path); const UglifyJsPlugin require(uglifyjs-webpack-plugin) //压缩 const CompressionWebpackPlugin require(compression-webpack-plugin) const isProduction process.env.NODE_ENV ! development;module.exp…

C#控制台程序中使用log4.net来输出日志

Apache log4net 库是一个帮助程序员将日志语句输出到各种输出目标的工具。log4net 是优秀的 Apache log4j™ 框架到 Microsoft .NE​​T 运行时的端口。 我喜欢他可以自定义输出,区分等级等特点。 导入库 我们在工程里添加NuGet的包。输入名称log4net &#xff0…

【Transformer系列】深入浅出理解Positional Encoding位置编码

一、参考资料 一文教你彻底理解Transformer中Positional Encoding Transformer Architecture: The Positional Encoding The Annotated Transformer Master Positional Encoding: Part I 如何理解Transformer论文中的positional encoding,和三角函数有什么关系&…

05ShardingSphere-JDBC水平分片

1、准备服务器 随着业务的扩大,订单表数据量不断增加,数据库面临存储压力,开始考虑对订单表进行水平分片。 将t_order表扩展为server-order0中的t_order0和t_order1、server-order1中的t_order0和t_order1 服务器规划:使用dock…

使用Python创建音乐播放器

1. 介绍 在本篇博客中,我们将介绍如何使用Python编程语言和wxPython模块创建一个简单的音乐播放器。我们将使用wxPython来构建用户界面,并借助pygame模块来实现音频播放的功能。 C:\pythoncode\new\quickplaywav.py 2. 使用方法 使用我们提供的源代码…

排查disabled问题之谷歌新版本特性

问题复现 最近我突然接手一个后台的bug,这个后台很久没有迭代更新了,我也不熟悉业务,所以只能看一下源码,问题很快就复现,测试的修复操作也很正确,就是因为渲染的input标签中存在disableddisabled’属性导…

2023 年您需要了解哪些类型的数据泄露?

到目前为止,所有公司都应该意识到网络安全威胁是任何企业面临的主要风险之一。其中,那些直接损害敏感数据的行为可能会造成特别严重的破坏。 目前,数据泄露的典型成本已接近 450 万美元(在过去三年中增加了 15%)&…

MySQL内外连接、索引特性

目录 内连接 外连接 索引特性 理解索引 删除索引 MySQL内外连接是一种用于联接两个或多个表的操作。内连接只返回满足连接条件的行,外连接返回满足条件和不满足条件的行。 内连接 SQL如下: SELECT ... FROM t1 INNER JOIN t2 ON 连接条件 [INNER …

使用香橙派 学习Linux的串口开发

串口的回顾 & 硬件接线 关于串口也是之前学习过很多次了,详见: 认识串口 和 蓝牙模块HC08_hc08蓝牙模块_mjmmm的博客-CSDN博客 串口的再认识-CSDN博客 香橙派提供了两路串口,第一路就是在刷机时串口连接的引脚(对应驱动ttyS0&…