0

0

深入浅析PHP中的建造者模式

青灯夜游

青灯夜游

发布时间:2021-07-19 19:51:23

|

2644人浏览过

|

来源于掘金--硬核项目经理

转载

在之前的文章《浅谈php中的中介者模式》中我们介绍了php中的中介者模式,下面本篇文章带大家了解一下php设计模式中的建造者模式。

深入浅析PHP中的建造者模式

建造者模式,也可以叫做生成器模式,builder这个词的原意就包含了建筑者、开发者、创建者的含义。很明显,这个模式又是一个创建型的模式,用来创建对象。那么它的特点是什么呢?从建筑上来说,盖房子不是一下子就马上能把一个房子盖好的,而是通过一砖一瓦搭建出来的。一个房子不仅有砖瓦,还有各种管道,各种电线等等,由它们各个不部分共同组成了一栋房子。可以说,建造者模式就是这样非常形象的由各种部件来组成一个对象(房子)的过程。

Gof类图及解释

GoF定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示

GoF类图

立即学习PHP免费学习笔记(深入)”;

1.png

代码实现

class Product
{
    private $parts = [];

    public function Add(String $part): void
    {
        $this->parts[] = $part;
    }

    public function Show(): void
    {
        echo PHP_EOL . '产品创建 ----', PHP_EOL;
        foreach ($this->parts as $part) {
            echo $part, PHP_EOL;
        }
    }
}

产品类,你可以把它想象成我们要建造的房子。这时的房子还没有任何内容,我们需要给它添砖加瓦。

interface Builder
{
    public function BuildPartA(): void;
    public function BuildPartB(): void;
    public function GetResult(): Product;
}

class ConcreteBuilder1 implements Builder
{
    private $product;

    public function __construct()
    {
        $this->product = new Product();
    }

    public function BuildPartA(): void
    {
        $this->product->Add('部件A');
    }
    public function BuildPartB(): void
    {
        $this->product->Add('部件B');
    }
    public function GetResult(): Product
    {
        return $this->product;
    }
}

class ConcreteBuilder2 implements Builder
{
    private $product;

    public function __construct()
    {
        $this->product = new Product();
    }

    public function BuildPartA(): void
    {
        $this->product->Add('部件X');
    }
    public function BuildPartB(): void
    {
        $this->product->Add('部件Y');
    }
    public function GetResult(): Product
    {
        return $this->product;
    }
}

建造者抽象及其实现。不同的开发商总会选用不同的品牌材料,这里我们有了两个不同的开发商,但他们的目的一致,都是为了去盖房子(Product)。

class Director
{
    public function Construct(Builder $builder)
    {
        $builder->BuildPartA();
        $builder->BuildPartB();
    }
}

构造器,用来调用建造者进行生产。没错,就是我们的工程队。它来选取材料并进行建造。同样的工程队,可以接不同的单,但盖出来的都是房子。只是这个房子的材料和外观不同,大体上的手艺还是共通的。

魔众盲盒系统
魔众盲盒系统

魔众盲盒系统,快速搭建在线盲盒系统。 “盲盒”已经深入到了各个行业,电商、化妆品、旅游、餐饮、 NFT等各个领域,都有自己独特的发展模式,但它们的玩法千差万别,让我们来看一看这套系统的构造。 运行环境: 操作系统Linux/Unix 或 Windows 软件环境Laravel 5.1的运行环境 Apache/Nginx PHP 5.5.9+ / PHP

下载
$director = new Director();
$b1 = new ConcreteBuilder1();
$b2 = new ConcreteBuilder2();

$director->Construct($b1);
$p1 = $b1->getResult();
$p1->Show();

$director->Construct($b2);
$p2 = $b2->getResult();
$p2->Show();

最后看看我们的实现,是不是非常简单,准备好工程队,准备好不同的建造者,然后交给工程队去生产就好啦!!

  • 其实这个模式要解决的最主要问题就是一个类可能有非常多的配置、属性,这些配置、属性也并不全是必须要配置的,一次性的实例化去配置这些东西非常麻烦。这时就可以考虑让这些配置、属性变成一个一个可随时添加的部分。通过不同的属性组合拿到不同的对象。
  • 上面那一条,在GoF那里的原文是:它使你改变一个产品的内部表示;它将构造代码和表示代码分开;它使你可以对构造过程进行更精细的控制。
  • 再说得简单一点,对象太复杂,我们可以一部分一部分的拼装它!
  • 了解过一点Android开发的一定不会陌生,创建对话框对象AlterDialog.builder
  • Laravel中,数据库组件也使用了建造者模式,你可以翻看下源码中Database\Eloquent和Database\Query目录中是否都有一个Builder.php

大家都知道,手机组装是一件复杂的过程,于是,不同型号的手机我们都有对应的图纸(Builder),将图纸和配件交给流水线上的工人(Director),他们就会根据图纸使用配件来生产出我们所需要的各种不同型号的手机(Product)。很明显,我们都是伟大的建造者,为我们的产业添砖加瓦!!!

完整代码:https://github.com/zhangyue0503/designpatterns-php/blob/master/16.builder/source/builder.php

实例

前面说过Android中有很多Dialog对话框都会用建造者模式来实现,作为一家手机厂的老板,定制化的Android系统也是非常重要的一个部分。就像X米一样,从MIUI入手,先拿下了软件市场,让大家觉得这个系统非常好用,然后再开始开发手机。这就说明软硬件的确是现代手机的两大最重要的组成部分,缺了谁都不行。这回,我们就用建造者模式简单的实现一套对话框组件吧!

对话框类图

2.png

完整源码:https://github.com/zhangyue0503/designpatterns-php/blob/master/16.builder/source/builder-dialog.php

<?php

class Dialog
{
    private $attributes = [];
    private $buttons = [];
    private $title = '';
    private $content = '';

    public function AddAttributes($attr)
    {
        $this->attributes[] = $attr;
    }
    public function AddButtons($button)
    {
        $this->buttons[] = $button;
    }
    public function SetTitle($title)
    {
        $this->title = $title;
    }
    public function SetContent($content)
    {
        $this->content = $content;
    }

    public function ShowDialog(){
        echo PHP_EOL, '显示提示框 === ', PHP_EOL;
        echo '标题:' . $this->title, PHP_EOL;
        echo '内容:' . $this->content, PHP_EOL;
        echo '样式:' . implode(',', $this->attributes), PHP_EOL;
        echo '按扭:' . implode(',', $this->buttons), PHP_EOL;
    }
}

interface Builder
{
    public function BuildAttribute($attr);
    public function BuildButton($button);
    public function BuildTitle($title);
    public function BuildContent($content);
    public function GetDialog();
}

class DialogBuilder implements Builder{
    private $dialog;
    public function __construct(){
        $this->dialog = new Dialog();
    }
    public function BuildAttribute($attr){
        $this->dialog->AddAttributes($attr);
    }
    public function BuildButton($button){
        $this->dialog->AddButtons($button);
    }
    public function BuildTitle($title){
        $this->dialog->SetTitle($title);
    }
    public function BuildContent($content){
        $this->dialog->SetContent($content);
    }
    public function GetDialog(){
        return $this->dialog;
    }
}

class DialogDirector {
    public function Construct($title, $content){

        $builder = new DialogBuilder();

        $builder->BuildAttribute('置于顶层');
        $builder->BuildAttribute('居中显示');

        $builder->BuildButton('确认');
        $builder->BuildButton('取消');

        $builder->BuildTitle($title);
        $builder->BuildContent($content);
        
        return $builder;
    }
}

class ModalDialogDirector {
    public function Construct($title, $content){

        $builder = new DialogBuilder();

        $builder->BuildAttribute('置于顶层');
        $builder->BuildAttribute('居中显示');
        $builder->BuildAttribute('背景庶照');
        $builder->BuildAttribute('外部无法点击');

        $builder->BuildButton('确认');
        $builder->BuildButton('取消');

        $builder->BuildTitle($title);
        $builder->BuildContent($content);
        
        return $builder;
    }
}

$d1 = new DialogDirector();
$d1->Construct('窗口1', '确认要执行操作A吗?')->GetDialog()->ShowDialog();

$d2 = new ModalDialogDirector();
$d2->Construct('窗口2', '确认要执行操作B吗?')->GetDialog()->ShowDialog();

说明

  • 这回我们的产品就有点复杂了,有标题、内容、属性、按扭等
  • 建造过程其实都一样,但这里我们主要使用了不同的构造器。普通对话框外面的东西是可以点击的,而模态窗口一般会有遮罩层,就是背景变成透明黑,而且外面的东西是不能再点击的
  • 如果每次都直接通过构造方法去实例化窗口类,那要传递的参数会很多,而现在这样,我们就可以通过建造者来进行组合,让对象具有多态的效果,能够呈现不同的形态及功能

原文地址:https://juejin.cn/post/6844903981836320781

作者:硬核项目经理

推荐学习:《PHP视频教程

相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
java多态详细介绍
java多态详细介绍

本专题整合了java多态相关内容,阅读专题下面的文章了解更多详细内容。

27

2025.11.27

github中文官网入口 github中文版官网网页进入
github中文官网入口 github中文版官网网页进入

github中文官网入口https://docs.github.com/zh/get-started,GitHub 是一种基于云的平台,可在其中存储、共享并与他人一起编写代码。 通过将代码存储在GitHub 上的“存储库”中,你可以: “展示或共享”你的工作。 持续“跟踪和管理”对代码的更改。

4145

2026.01.21

discuz database error怎么解决
discuz database error怎么解决

discuz database error的解决办法有:1、检查数据库配置;2、确保数据库服务器正在运行;3、检查数据库表状态;4、备份数据;5、清理缓存;6、重新安装Discuz;7、检查服务器资源;8、联系Discuz官方支持。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

227

2023.11.20

数据库三范式
数据库三范式

数据库三范式是一种设计规范,用于规范化关系型数据库中的数据结构,它通过消除冗余数据、提高数据库性能和数据一致性,提供了一种有效的数据库设计方法。本专题提供数据库三范式相关的文章、下载和课程。

385

2023.06.29

如何删除数据库
如何删除数据库

删除数据库是指在MySQL中完全移除一个数据库及其所包含的所有数据和结构,作用包括:1、释放存储空间;2、确保数据的安全性;3、提高数据库的整体性能,加速查询和操作的执行速度。尽管删除数据库具有一些好处,但在执行任何删除操作之前,务必谨慎操作,并备份重要的数据。删除数据库将永久性地删除所有相关数据和结构,无法回滚。

2111

2023.08.14

vb怎么连接数据库
vb怎么连接数据库

在VB中,连接数据库通常使用ADO(ActiveX 数据对象)或 DAO(Data Access Objects)这两个技术来实现:1、引入ADO库;2、创建ADO连接对象;3、配置连接字符串;4、打开连接;5、执行SQL语句;6、处理查询结果;7、关闭连接即可。

357

2023.08.31

MySQL恢复数据库
MySQL恢复数据库

MySQL恢复数据库的方法有使用物理备份恢复、使用逻辑备份恢复、使用二进制日志恢复和使用数据库复制进行恢复等。本专题为大家提供MySQL数据库相关的文章、下载、课程内容,供大家免费下载体验。

259

2023.09.05

vb中怎么连接access数据库
vb中怎么连接access数据库

vb中连接access数据库的步骤包括引用必要的命名空间、创建连接字符串、创建连接对象、打开连接、执行SQL语句和关闭连接。本专题为大家提供连接access数据库相关的文章、下载、课程内容,供大家免费下载体验。

329

2023.10.09

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

76

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

相关下载

更多

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 13.4万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 11.3万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 1.0万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号