前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >大牧絮叨设计模式:建造者模式

大牧絮叨设计模式:建造者模式

作者头像
大牧莫邪
发布于 2019-07-23 02:11:48
发布于 2019-07-23 02:11:48
40100
代码可运行
举报
运行总次数:0
代码可运行

1、 建造模式 概述

建造模式(Builder)[GOF95]是一种对象的创造模式。主要责任是在程序中创建较为复杂的对象,企业项目中在运行环境初始化时经常使用的一种创建模式。

1.1、 核心组件

建造模式和工厂模式极为相似,都是将对象的构建过程和对象的业务处理分离开来,让不同的类型分别承担对象的创建和对象的使用的责任。

建造模式在构建对象的过程中,目标对象一般都是较为复杂的多个对象或者组件内聚并添加一定业务逻辑的对象组件,并且内部对象构建过程区分前后顺序,核心组件如下:

  • 抽象建造者(Builder):规范建造者的一个抽象接口,规范产品建造过程中的步骤和规范,该接口独立于业务逻辑之外,是基于功能拓展的一个抽象依赖。
  • 具体建造者(ConcreteBuilder):该类型与具体业务逻辑紧密相关,实现了抽象建造者接口,是具体产品构建过程的执行者。
  • 零件/聚合对象(AggregationProduct):该类型的对象是最终对象中包含的具体组成部分,该组成部分可能是对象,也可能是组件或者业务逻辑。
  • 产品对象(Product):最终的产品对象,该产品对象是具体建造者最终返回的构建结果,也是我们建造者模式最终产生的和业务逻辑紧密结合的对象。

image.png

1.2、 优点缺陷

优点:

复杂对象的创建分步骤执行,开发难度降低,可读性提升

对象的创建过程和业务处理过程解耦合

缺陷:

系统复杂度提升

系统资源消耗增加

2、 Java 实现

2.1、 抽象建造者Builder

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.damu.builder;

/**
 * <p>项目文档: 产品 抽象建造者 </p>
 *
 * @author <a href="https://github.com/laomu/laomu.github.io">大牧</a>
 * @version V1.0
 */
public interface Builder<T> {
    /**
     * 第一个构建步骤
     */
    void builderPart1();

    /**
     * 第二个构建步骤
     */
    void builderPart2();

    /**
     * 获取最终产品
     * @return 最终产品
     */
    T retrieveResult();
}

2.2、 内聚组件Aggregation Product

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.damu.product;

/**
 * <p>项目文档: 复杂对象-组成部分1-eg:楼房</p>
 *
 * @author <a href="https://github.com/laomu/laomu.github.io">大牧</a>
 * @version V1.0
 */
public class Part1Component {

    private String information;

    public Part1Component(String information) {
        this.information = information;
    }

    public String getInformation() {
        return information;
    }

    public void setInformation(String information) {
        this.information = information;
    }
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.damu.product;

/**
 * <p>项目文档: 复杂对象-组成部分1-eg:物业</p>
 *
 * @author <a href="https://github.com/laomu/laomu.github.io">大牧</a>
 * @version V1.0
 */
public class Part2Component {

    private String information;

    public Part2Component(String information) {
        this.information = information;
    }

    public String getInformation() {
        return information;
    }

    public void setInformation(String information) {
        this.information = information;
    }
}

2.3、 具体产品Product

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.damu.product;

/**
 * <p>项目文档: 具体产品类-eg:小区</p>
 *
 * @author <a href="https://github.com/laomu/laomu.github.io">大牧</a>
 * @version V1.0
 */
public class Product {
    private String information;
    private Part1Component part1;
    private Part2Component part2;

    public String getInformation() {
        return information;
    }

    public void setInformation(String information) {
        this.information = information;
    }

    public Part1Component getPart1() {
        return part1;
    }

    public void setPart1(Part1Component part1) {
        this.part1 = part1;
    }

    public Part2Component getPart2() {
        return part2;
    }

    public void setPart2(Part2Component part2) {
        this.part2 = part2;
    }
}

2.4、 具体建造者ConcreteBuilder

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.damu.builder;

import com.damu.product.Part1Component;
import com.damu.product.Part2Component;
import com.damu.product.Product;

/**
 * <p>项目文档: 具体建造者</p>
 *
 * @author <a href="https://github.com/laomu/laomu.github.io">大牧</a>
 * @version V1.0
 */
public class ConcreteBuilder implements Builder<Product> {

    private Product product;
    @Override
    public void builderPart1() {
        // builder part1
        Part1Component part1 = new Part1Component("国际工厂-盖楼");
        // other business procedure
        // aggregation
        product.setPart1(part1);
    }

    @Override
    public void builderPart2() {
        // builder part2
        Part2Component part2 = new Part2Component("华夏物理-管理");
        // other business procedure
        // aggregation
        product.setPart2(part2);
    }

    @Override
    public Product retrieveResult() {
        // builder product
        product = new Product();
        product.setInformation("清风小区");
        // step1
        this.builderPart1();
        // other business procedure
        // step2
        this.builderPart2();
        return product;
    }
}

2.5、业务消费者Consumer

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.damu.main;

import com.damu.builder.Builder;
import com.damu.builder.ConcreteBuilder;
import com.damu.product.Product;

/**
 * <p>项目文档: 消费者</p>
 *
 * @author <a href="https://github.com/laomu/laomu.github.io">大牧</a>
 * @version V1.0
 */
public class Consumer {
    public static void main(String[] args) {
        // 获取建造工厂
        Builder<Product> builder = new ConcreteBuilder();

        // 获取小区对象
        Product product = builder.retrieveResult();

        System.out.println(product);
    }
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 执行结果
Product{information='清风小区', part1=Part1Component{information='国际工厂-盖楼'}, part2=Part2Component{information='华夏物理-管理'}}

3、 Python 实现

3.1、 抽象建造者Builder

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import abc


class Builder(metaclass=abc.ABCMeta):
    """抽象建造者"""
    def retrieve_result(self):
        """获取产品对象的方法"""
        raise NotImplemented("该方法必须在子类中实现")

3.2、 内聚组件Aggregation Product

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Part1Component:
    """产品部件1"""
    pass


class Part2Component:
    """产品部件2"""
    pass

3.3、 具体产品Product

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import abc

class Product(metaclass=abc.ABCMeta):
    """建造者产品接口"""

    @abc.abstractmethod
    def information(self):
        raise NotImplemented("该方法必须实现.")
        
class ConcreteProduct(Product):
    """具体产品对象"""

    def __init__(self):
        self.part1 = None
        self.part2 = None

    def information(self):
        print("目标对象")

3.4、 具体建造者ConcreteBuilder

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class ConcreteBuilder(Builder):
    """具体建造类"""

    def __init__(self):
        """初始化"""
        self.product = ConcreteProduct()

    def __build_part1(self):
        # 构建零件对象
        part1_component = Part1Component()
        # 业务受理
        # 聚合
        self.product.part1 = part1_component

    def __build_part2(self):
        # 构建零件对象
        part2_component = Part2Component()
        # 业务受理
        # 聚合
        self.product.part2 = part2_component

    def retrieve_result(self):
        return self.product

3.5、业务消费者Consumer

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if __name__ == "__main__":
    """测试代码"""
    # 创建建造者对象
    builder = ConcreteBuilder()
    # 建造目标对象
    product = builder.retrieve_result()
    print(product)

4、 Go 实现

4.1、 抽象建造者Builder

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
type Builder interface {
  SetName(name string) Builder
  SetArms(arms string) Builder
  Build() *Character
}

4.2、 具体产品Product

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
type Character struct {
  Name string
  Arms string
}

func (p *Character) SetName(name string) {
  p.Name = name
}

func (p *Character) SetArms(arms string) {
  p.Arms = arms
}

func (p Character) GetName() string {
  return p.Name
}

func (p Character) GetArms() string {
  return p.Arms
}

4.3、 具体建造者ConcreteBuilder

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
type CharacterBuilder struct {
  character *Character
}

func (p *CharacterBuilder) SetName(name string) Builder {
  if p.character == nil {
    p.character = &Character{}
  }
  p.character.SetName(name)
  return p
}

func (p *CharacterBuilder) SetArms(arms string) Builder {
  if p.character == nil {
    p.character = &Character{}
  }
  p.character.SetArms(arms)
  return p
}

func (p *CharacterBuilder) Build() *Character {
  return p.character
}

4.4、业务消费者Consumer

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
type Consumer struct {
  builder Builder
}

func (p Director) Create(name string, arms string) *Character {
  return p.builder.SetName(name).SetArms(arms).Build()
}

func main() {
  var builder Builder = &CharacterBuilder {}
  var consumer *Consumer = &Consumer {builder: builder}
  var character *Character = director.Create("loader", "AK47")
  fmt.Println(character.GetName() + "," + character.GetArms())
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019.07.22 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
又遇500
宽带换套餐迟了,只好销户再开,也就从前天起没法上网了,昨天早上用手机登陆网站的时候发现500错误了,以为只是一会,结果晚上了还没好,就联系电信机房把我的宽带账号激活,赶紧看看出啥事了。
空空裤兜
2023/03/03
5520
502错误处理思路
最近几天,一个站不时502,另一个却好好的,很是纳闷。最开始以为是php或者nginx卡住了,重启两个服务后恢复,后来重启没有作用,更换了php和nginx的版本后问题解决,再后来重启服务、重启vps都不能解决问题,一直既往的一个站点正常,另一个站502错误。
空空裤兜
2023/03/03
7350
鼠标点击特效tunneler
2022.10.15update:虽然找到了JS文件,现在已经不能使用了,有需要文件自行研究的留言。
空空裤兜
2023/03/03
2.7K0
友链移至首页
买了木木的主题有一段时间了,修修改改的折腾到现在,虽然还有错误的地方,但是相对来说不是很严重,还在可以接受的范围内,比如评论时不知道什么时候会出现的评论框不能输入,发布按钮上的倒计时也会停留在15秒不动,可能是代码冲突,先放着吧。
空空裤兜
2023/03/03
1.3K0
友链移至首页
道道通出现“no mapdb1”错误
善领引导凯立德成功。引导道道通的时候提示“No mapdb1”,搜了很多解决方法,基本都是一个抄另一个,通过我不断的楼上楼下跑,修改、测试,终于找到一种目前还没搜到的办法,当然,也很简单。
空空裤兜
2023/03/03
2990
道道通出现“no mapdb1”错误
自建随机图片API
将上述代码放入新建的PHP文件中,名称随意,我的是img.php,同级建立images目录,将图片直接放到images中即可。
空空裤兜
2023/03/03
9320
通过DenyHosts阻止SSH暴力攻击教程
Denyhosts是一个Linux系统下阻止暴力破解SSH密码的软件,它的原理与DDoS Deflate类似,可以自动拒绝过多次数尝试SSH登录的IP地址,防止互联网上某些机器常年破解密码的行为,也可以防止黑客对SSH密码进行穷举。
空空裤兜
2023/03/03
6710
wordpress中文论坛被黑了
自从博客换了wordpress程序后,经常泡的论坛就是wordpress中文论坛,看到博友们分享的主题、插件,更多的是结识了一群博友,互访,灌水。
空空裤兜
2023/03/03
4570
wordpress中文论坛被黑了
为tag添加链接
最近转了很多博客,看到很多人的文章内有tag的链接,自己以前也用过这样的插件,比如all in one seo,key-link好像,感觉都不怎么好。
空空裤兜
2023/03/03
6050
为tag添加链接
源码搭建tiny tinyrss订阅系统
安装ttrss也有两种比较常见的方案,一种是docker,一种是通过源码。这里,我们采用源码的方式。
空空裤兜
2023/03/03
6840
源码搭建tiny tinyrss订阅系统
Gravatar头像缓存本地化
Gravatar头像因为某种原因打不开,解决办法有换源、本地缓存等,上个主题不知道哪里的问题,换源始终不行,评论区一水的葫芦娃和爷爷,今天翻教程,找到这篇本地缓存教程,来自《wordpress加速之Gravatar头像缓存本地化》。
空空裤兜
2023/03/03
9120
Gravatar头像缓存本地化
搬家到MC
搬到洛杉矶MC机房了,感觉上速度和linode东京差别不大,记录下搬家中的小问题。
空空裤兜
2023/03/03
1.3K0
搬家到MC
自动填写评论者信息
前几天在木木的博客看到下面这段代码,当时也没在意,今天在毕扬那里又见到了,那么折腾下吧。
空空裤兜
2023/03/03
6530
Postfix配置记录
手贱,又搞了个vps,用就久了sendmail,想着换换口味,于是就postfix。Postfix安装很简单,centos6.4好像默认已经安装好了,略过不叙。主要记录一下配置中出现的一些问题。
空空裤兜
2023/03/03
8400
搞定侧边栏TAB选项卡
竖着排列确实会在网速卡的时候,随机日志,最新日志,热评日志会连在一起显示30篇文章,太不美观了。
空空裤兜
2023/03/03
1.2K0
添加微信开放平台
在微信开放平台刚出来的时候,就申请了一个号码,并热乎乎的发布了出来,也关注了几个公共号码,一时间微信消息此起彼伏,好不热闹,不过空空裤兜只是注册了号码,并没有发布消息,所以这个所谓的平台是一片冷清。
空空裤兜
2023/03/03
3K0
添加微信开放平台
Linux Apache主机设置ZBLOG PHP防盗链图片的方法
我们一般选择的云服务器都是有带宽或者流量限制的,甚至我们在将网站的图片静态文件丢入对象存储,对象存储空间也是按照流量计费。如果我们的网站被盗链图片,可能会导致流量流失比较大,当然是有消耗我们的成本的,于是我们会使用到防盗链的方法。
老蒋
2021/12/27
6850
给WordPress评论添加背景图片
很多博客的评论框有背景图片,因为担心服务器的响应时间,一直都没设置,为了鼓励访客评论,我也给评论框添加了背景图片,实现的方法是very very简单。
空空裤兜
2023/03/03
6480
给WordPress评论添加背景图片
标题载入添加loading状态
昨天不知道在谁的博客看到一个特效,鼠标移到标题的时候,标题会向右缓缓移动,感觉不错,还留了言,博主没有回复,我现在也不急的是谁的博客了。
空空裤兜
2023/03/03
8740
初步折腾Varnish
开始安装就遇到麻烦了,总是提示安装不成功,换了一个又一个的源,最后总算在谷哥的帮助下安装成功。
空空裤兜
2023/03/03
4230
相关推荐
又遇500
更多 >
LV.0
这个人很懒,什么都没有留下~
目录
  • 1、 建造模式 概述
    • 1.1、 核心组件
    • 1.2、 优点缺陷
  • 2、 Java 实现
    • 2.1、 抽象建造者Builder
    • 2.2、 内聚组件Aggregation Product
    • 2.3、 具体产品Product
    • 2.4、 具体建造者ConcreteBuilder
    • 2.5、业务消费者Consumer
  • 3、 Python 实现
    • 3.1、 抽象建造者Builder
    • 3.2、 内聚组件Aggregation Product
    • 3.3、 具体产品Product
    • 3.4、 具体建造者ConcreteBuilder
    • 3.5、业务消费者Consumer
  • 4、 Go 实现
    • 4.1、 抽象建造者Builder
    • 4.2、 具体产品Product
    • 4.3、 具体建造者ConcreteBuilder
    • 4.4、业务消费者Consumer
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档