当前位置: 首页 > news >正文

hyperf 创建型(单例、工厂、建造者、原型)

---1. 单例模式 — 全局只有一个 ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 大白话: 整个应用只创建一个实例,所有地方用的都是同一个对象。 生活比喻: 公司只有一个CEO,不管谁找CEO,找到的都是同一个人。 什么时候用: 数据库连接池、Redis连接、配置类、日志类。 // Hyperf 里最简单的方式:直接用容器,天然单例 // config/autoload/dependencies.phpreturn[RedisClient::class=>RedisClient::class, // 容器默认就是单例];// 手动实现单例 class Config{private static ?Config$instance=null;private array$data=[];// 构造函数私有,外部不能 new privatefunction__construct(){$this->data=require'config.php';}public staticfunctiongetInstance(): static{if(static::$instance===null){static::$instance=new static();}returnstatic::$instance;}publicfunctionget(string$key): mixed{return$this->data[$key]?? null;}}// 用法:不管调多少次,都是同一个对象$config1=Config::getInstance();$config2=Config::getInstance();var_dump($config1===$config2);// true,同一个 Hyperf 协程注意点: // 协程环境下,单例共享数据会有并发问题 // 用 Context 存请求级别的数据,不要存在单例属性里 class UserContext{public staticfunctionset(User$user): void{Context::set('current_user',$user);// 每个协程独立}public staticfunctionget(): ?User{returnContext::get('current_user');}}---2. 工厂模式 — 专门负责造对象 大白话: 你不用关心对象怎么创建的,告诉工厂你要什么,工厂给你造好。 生活比喻: 你去餐厅点菜,不用管厨房怎么做,说"来份宫保鸡丁",端上来就行。 什么时候用: 创建逻辑复杂、根据条件创建不同对象。 简单工厂 // 根据支付类型,创建不同支付对象 interface PaymentInterface{publicfunctionpay(int$amount): bool;}class AlipayPayment implements PaymentInterface{publicfunctionpay(int$amount): bool{echo"支付宝支付 {$amount} 元";returntrue;}}class WechatPayment implements PaymentInterface{publicfunctionpay(int$amount): bool{echo"微信支付 {$amount} 元";returntrue;}}// 工厂:你告诉我类型,我给你造 class PaymentFactory{public staticfunctioncreate(string$type): PaymentInterface{returnmatch($type){'alipay'=>new AlipayPayment(),'wechat'=>new WechatPayment(), default=>throw new\InvalidArgumentException("不支持的支付方式: {$type}"),};}}// 用法:不用关心怎么 new 的$payment=PaymentFactory::create('alipay');$payment->pay(100);工厂方法(结合 Hyperf 容器) // 更优雅:用 Hyperf 容器做工厂 class PaymentFactory{publicfunction__construct(private ContainerInterface$container){}publicfunctioncreate(string$type): PaymentInterface{$map=['alipay'=>AlipayPayment::class,'wechat'=>WechatPayment::class,];if(!isset($map[$type])){throw new\InvalidArgumentException("不支持: {$type}");}return$this->container->get($map[$type]);}}// Controller 里用 class OrderController{publicfunction__construct(private PaymentFactory$factory){}publicfunctionpay(Request$request): ResponseInterface{$payment=$this->factory->create($request->input('type'));$payment->pay($request->input('amount'));return$this->response->json(['status'=>'ok']);}}---3. 建造者模式 — 一步步组装复杂对象 大白话: 对象太复杂,参数太多,一步步设置,最后 build()出来。 生活比喻: 装修房子,先定墙色、再定地板、再定家具,最后验收交付。不是一次性全说完。 什么时候用: 构造参数超过4个、对象有很多可选配置、需要链式调用。 // 场景:发送消息,有很多可选项 class Message{privatefunction__construct(publicreadonlystring$to, publicreadonlystring$content, publicreadonlystring$type, publicreadonly?string$title, publicreadonlyint$priority, publicreadonly?array$extra,){}public staticfunctionbuilder(string$to, string$content): MessageBuilder{returnnew MessageBuilder($to,$content);}}class MessageBuilder{private string$type='text';private ?string$title=null;private int$priority=0;private ?array$extra=null;publicfunction__construct(private string$to, private string$content,){}publicfunctiontype(string$type): static{$this->type=$type;return$this;// 返回自身,支持链式调用}publicfunctiontitle(string$title): static{$this->title=$title;return$this;}publicfunctionpriority(int$priority): static{$this->priority=$priority;return$this;}publicfunctionextra(array$extra): static{$this->extra=$extra;return$this;}publicfunctionbuild(): Message{returnnew Message(to:$this->to, content:$this->content, type:$this->type, title:$this->title, priority:$this->priority, extra:$this->extra,);}}// 用法:链式调用,清晰直观$message=Message::builder('13800138000','您的订单已发货')->type('sms')->title('订单通知')->priority(1)->extra(['order_id'=>1001])->build();// 实际场景:构建复杂查询条件 class UserQueryBuilder{private array$conditions=[];private ?int$limit=null;private string$orderBy='created_at';publicfunctionactive(): static{$this->conditions['status']=1;return$this;}publicfunctionvip(): static{$this->conditions['is_vip']=1;return$this;}publicfunctionlimit(int$limit): static{$this->limit=$limit;return$this;}publicfunctionorderBy(string$field): static{$this->orderBy=$field;return$this;}publicfunctionbuild(): Builder{$query=User::query();foreach($this->conditions as$field=>$value){$query->where($field,$value);}if($this->limit){$query->limit($this->limit);}return$query->orderBy($this->orderBy);}}// 用法$users=(new UserQueryBuilder())->active()->vip()->limit(10)->orderBy('created_at')->build()->get();---4. 原型模式 — 复制一个现成的 大白话: 创建新对象太麻烦,直接克隆一个现有的,再改改就行。 生活比喻: 合同模板,每次不从头写,复制一份模板改改就发出去。 什么时候用: 对象初始化成本高、需要大量相似对象、配置类对象复用。 // 场景:邮件模板,基础配置一样,只改收件人和内容 class EmailTemplate{publicfunction__construct(public string$from='noreply@example.com', public string$to='', public string$subject='', public string$body='', public array$cc=[], public string$charset='UTF-8', public string$contentType='text/html',){}// 克隆方法 publicfunctionclone(): static{returnclone$this;}// 链式修改 publicfunctionwithTo(string$to): static{$new=$this->clone();$new->to=$to;return$new;}publicfunctionwithSubject(string$subject): static{$new=$this->clone();$new->subject=$subject;return$new;}publicfunctionwithBody(string$body): static{$new=$this->clone();$new->body=$body;return$new;}}// 用法:定义一个基础模板$baseTemplate=new EmailTemplate(from:'order@myshop.com', charset:'UTF-8', contentType:'text/html',);// 克隆出不同邮件,不影响原模板$orderEmail=$baseTemplate->withTo('user@example.com')->withSubject('您的订单已确认')->withBody('<h1>订单确认</h1>');$shipEmail=$baseTemplate->withTo('user@example.com')->withSubject('您的订单已发货')->withBody('<h1>订单发货</h1>');// 注意:clone 是浅拷贝,对象属性要手动深拷贝 class Order{public array$items=[];public Address$address;// 对象属性 publicfunction__clone(){// 深拷贝对象属性,否则克隆体和原对象共享同一个 Address$this->address=clone$this->address;// 数组是值类型,自动深拷贝,不用处理}}--- 四种模式对比 ┌────────┬────────────────────┬──────────────┐ │ 模式 │ 解决什么问题 │ 一句话记忆 │ ├────────┼────────────────────┼──────────────┤ │ 单例 │ 全局只要一个实例 │ 独生子 │ ├────────┼────────────────────┼──────────────┤ │ 工厂 │ 不想关心怎么 new │ 点菜不进厨房 │ ├────────┼────────────────────┼──────────────┤ │ 建造者 │ 参数太多、分步构建 │ 装修房子 │ ├────────┼────────────────────┼──────────────┤ │ 原型 │ 复制现有对象改改用 │ 复印合同模板 │
http://www.cnnetsun.cn/news/2105692.html

相关文章:

  • 用100道题拿下你的算法面试(字符串篇-8):回文子串数目
  • 3步部署DamaiHelper抢票神器:多平台自动化抢票终极指南
  • Python在TVA算法架构优化中的创新应用(九)
  • Docker运行AI模型必踩的3个安全雷区:从容器逃逸到模型窃取的全链路防护指南
  • 永磁同步电机参数辨识与状态估计:扩展卡尔曼滤波(EKF)在RLS性能不足条件下的深度应用研究
  • 2025届学术党必备的降AI率助手实际效果
  • 如何将 Jupyter Notebook (.ipynb) 文件转换为 Python (.py) 文件
  • 【央行金科局内部通报引用】:MCP 2026配置偏差导致审计否决率飙升42%——你的配置还停留在2023版吗?
  • 如何快速掌握微信自动化:新手到高手的终极指南
  • 深入理解Android系统开发:SDK方向工程师的全面指南
  • 远程开发环境冷启动从47s到≤3s,全链路优化实战,含Docker Compose缓存策略、devcontainer.json深度配置与GPU直通配置
  • LlamaIndex.TS停更启示:从RAG框架设计看LLM应用数据层演进
  • 5分钟掌握B站视频永久保存技巧:m4s-converter完整使用指南
  • 2026年TOP10 AIGC检测工具汇总,终于找到可以免费查AI率的了!
  • 怎样高效部署ClearerVoice-Studio:专业级AI语音处理工具包全面指南
  • 一站式解决方案:Ledger 官方授权店详细购买与服务全指南
  • LinkSwift:跨平台网盘直链解析引擎的技术架构与配置指南
  • 校园小情书微信小程序源码 _ 社区小程序前后端开源 _ 校园表白墙交友小程序
  • 重构仿真工作流:从手动操作到智能自动化的范式革命
  • 5分钟掌握WebToEpub:将网页小说转为电子书的终极解决方案
  • 桌面后端开发本地服务与系统集成
  • HTTPS-加密变迁-对称-非对称-中间人攻击-证书全流程
  • 千问3.5-2B助力STM32开发:嵌入式系统代码注释与文档生成
  • Claude Code 工程化配置指南:从代码助手到超级队友的进化
  • SQL CREATE DATABASE
  • Fan Control完整教程:3步实现Windows风扇智能控制
  • AI大模型开始“接管测试”:文本、语音、视觉,谁才是效率杀手锏?
  • 如何快速部署与优化RTL8852BE Wi-Fi 6驱动?终极完整指南
  • DSGE_mod:宏观经济建模的权威Dynare模型库完全指南
  • 移动端UI自动化测试新框架Maestro:声明式语法与实战指南