深入 Laravel 内核之工厂模式
英雄与行为,依赖的诞生
首先定义一个英雄,英雄具有一些行为:
class Hero {
protected $behavior = [];
public function show()
{
var_dump($this->behavior);
}
}
然后定义一种名为攻击行为:
class Attack {
protected $value = 0;
public function __construct($value)
{
$this->value = $value;
}
}
改造一下英雄类,让英雄在出生的时候具有攻击行为:
class Hero {
protected $behavior = [];
public function __construct()
{
array_push($this->behavior, new Attack(10));
}
public function show()
{
var_dump($this->behavior);
}
}
这样,英雄和某个具体的行为就产生了一种依赖关系。
英雄学会了越来越多的行为
随着英雄的成长,英雄学会了越来越多的行为:
class Defend {
protected $value = 0;
public function __construct($value){}
}
class Move {
protected $speed;
public function __construct($speed){}
}
class Skill1 {
protected $name = '暴击';
public function __construct(){}
}
class Skill2 {
protected $name = '眩晕';
public function __construct(){}
}
改造一下英雄类,让英雄在出生的时候具有这些行为:
class Hero {
protected $behavior = [];
public function __construct()
{
array_push($this->behavior, new Attack(10));
array_push($this->behavior, new Defend(5));
array_push($this->behavior, new Move(30));
array_push($this->behavior, new Skill1());
array_push($this->behavior, new Skill2());
}
public function show()
{
var_dump($this->behavior);
}
}
随着行为的增加,暴露出了几个问题:
- 每增加一种行为,就必须修改一次英雄类;
- 如果想让不同的英雄拥有不同的技能,需要创建很多不同的英雄类。
通过工厂模式,实现依赖转移
定义一个行为工厂,英雄出生时可以在行为工厂中挑选行为:
class BehaviorFactory
{
public function makeBehavior($behaviorName, $options=[])
{
switch ($behaviorName) {
case 'Attack': return new Attack($options[0]);
case 'Defend': return new Defend($options[0]);
case 'Move': return new Move($options[0]);
case 'Skill1': return new Skill1();
case 'Skill2': return new Skill2();
}
}
}
修改英雄类,让英雄可以去工厂中学习行为:
class Hero
{
protected $behavior = [];
public function __construct(array $behaviors)
{
// 初始化工厂
$factory = new BehaviorFactory();
// 通过工厂提供的方法制造需要的模块
foreach ($behaviors as $behaviorName => $behaviorOptions) {
$this->behavior[] = $factory->makeBehavior($behaviorName, $behaviorOptions);
}
}
}
$hero = new Hero([
'Attack' => [10],
'Defend' => [5],
'Move' => [30],
'Skill1' => [],
]);
引入工厂模式,我们解决了上述的两个问题:
- 使得英雄类不再依赖其他行为类,增加任意一种行为,都不需要修改英雄类;
- 如果想要不同的英雄拥有不同的技能,在英雄出生时选择即可。
但同时我们也引入了一个新的问题,每增加一种行为,就需要在工厂中增加一条生产线。
后面,我们将讲解如果使用一个更高级的工厂-服务容器来解决工厂模式存在的问题。
深入 Laravel 内核之工厂模式的更多相关文章
- 深入 Laravel 内核之外观模式(门面模式)
门面模式核心内容: 客户端与子系统的通信通过外观对象进行: 外观对象封装一系列子系统的具体对应方法,对客户端只需暴露一个单一的入口方法: 客户端通过访问外观对象即可调用子系统的基础方法,无需关心子系统 ...
- laravel 工厂模式到容器
下面实现了查人拥有超能力的三种方式 第一种最基本的类引用实现 1 <?php /** * 目的:代码的完善来说明从 基础类的调用到 工厂类的使用 再到容器的出现的原因 * (首先要明白工厂类和容 ...
- 23种设计模式--工厂模式-Factory Pattern
一.工厂模式的介绍 工厂模式让我们相到的就是工厂,那么生活中的工厂是生产产品的,在代码中的工厂是生产实例的,在直白一点就是生产实例的类,代码中我们常用new关键字,那么这个new出来的实例 ...
- javascript工厂模式和构造函数模式创建对象
一.工厂模式 工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程(本书后面还将讨论其他设计模式及其在JavaScript 中的实现).考虑到在ECMAScript 中无法创 ...
- PHP设计模式(三)抽象工厂模式(Abstract Factory For PHP)
一.什么是抽象工厂模式 抽象工厂模式的用意为:给客户端提供一个接口,可以创建多个产品族中的产品对象 ,而且使用抽象工厂模式还要满足以下条件: 系统中有多个产品族,而系统一次只可能消费其中一族产品. 同 ...
- PHP设计模式(一)简单工厂模式 (Simple Factory For PHP)
最近天气变化无常,身为程序猿的寡人!~终究难耐天气的挑战,病倒了,果然,程序猿还需多保养自己的身体,有句话这么说:一生只有两件事能报复你:不够努力的辜负和过度消耗身体的后患.话不多说,开始吧. 一.什 ...
- 设计模式之工厂模式VS抽象工厂
一.工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的. 工厂模式在<Java与模式>中分为三类:1)简单工厂模式(Simple Factor ...
- 菜鸟理解的工厂模式(Factory Pattern)是什么样子的?
直接开始说了,不浪费园友宝贵的时间! 什么是工厂模式? 在学习前,先问一下:"它是什么?". 工厂模式,它是项目里面常用的设计模式之一. 它是属于创建型模式,简单的理解创建型模式就 ...
- PHP 面向对象编程和设计模式 (3/5) - 单例模式和工厂模式
PHP高级程序设计 学习笔记 2014.06.11 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容 ...
随机推荐
- 阿里云esc 安装 docker
1. 更新 yum 到最新: yum update (用 root 用户登录,无需加 sudo,如果不是,需要加,即 yum update ) 2. 安装软件包:yum-util(提供 yum-co ...
- 设计模式学习笔记之看懂UML类图
什么是UML: UML(统一建模语言)是当今软件设计的标准图标式语言.对于一个软件系统而言,UML语言具有以下的功能:可视化功能.说明功能.建造功能和建文档功能. UML都包括什么类型的图: 使用案例 ...
- .net 5 开发部署B/S程序。
现在.net 6 已经出来了,visualStudio 2022也发行预览版了. 自 .net5 发布,.net core 与.net framework 已经走向统一.确实越来越好用了. 现在.ne ...
- java多线程5:线程间的通信
在多线程系统中,彼此之间的通信协作非常重要,下面来聊聊线程间通信的几种方式. wait/notify 想像一个场景,A.B两个线程操作一个共享List对象,A对List进行add操作,B线程等待Lis ...
- Simple iPhone Keychain Access
Simple iPhone Keychain Access Mar 29th, 2010 9:14 pm The keychain is about the only place that an iP ...
- 童鞋,[HttpClient发送文件] 的技术实践请查收
1.荒腔走板 前几天有个童鞋在群里面问:怎么使用HttpClient发送文件? 之前我写了一个ABP上传文件,主要体现的是服务端,上传文件的动作是由前端小姐姐完成的, 我还真没有用HttpClient ...
- 【密码学】AES简单学习
欧拉函数 公式 φ(n)=(p-1)(q-1) 小于x并且和x互质的数的个数 相关概念 因数:a*b=c 那么就称 a.b 是 c 的因数 素数:一个数如果除了1与它本身之外没有其他的因数,那么 ...
- sublime打开中文文件乱码以及打开文件出现.dump
一.中文乱码 原因:中文文件由gbk编码,刚安装的sublime不支持转码 解决方法:调用ctrl+shift+p,输入:install package,回车,在稍后弹出的安装包框中搜索:Conver ...
- WebRTC + WebSocket 实现视频通话
前言 WebRTC WebRTC(Web Real-Time Communication).Real-Time Communication,实时通讯. WebRTC能让web应用和站点之间选择性地分享 ...
- LuoguP7852 「EZEC-9」Yet Another Easy Problem 题解
Content 给定 \(n,m\),你需要输出一个长度为 \(n\) 的排列,满足该排列进行不超过 \(m\) 次交换操作可以得到的最小的字典序最大. 数据范围:\(T\) 组数据,\(1\leqs ...