Laravel 工厂模式的应用及组件可扩展性探讨

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

OUSTN
oustn 2017
12
可扩展的组件
Parser Manager
class ParserManager { protected $customCreator = []; public function parser($name = null) { $name = $name ?: $this->getDefault(); return $this->get($name); } private function getDefault() { return config('parser.default'); } private function get($name) { if (isset($this->customCreator[$name])) { return call_user_func($this->customCreator[$name]); } $creator = 'create' . studly_case($name) . 'Parser'; return $this->$creator(); }
产品 C
02 03
客户端不再需要了解详细的产品类类名,只需要了解产品对应的参数即可,对于 一些复杂的类名减少了记忆的难度 通过引入配置文件,可以在不修改任何客户端代码的情况下更换具体产品类,在 一定程度上提高了系统的灵活性
OUSTN
oustn 2017
3
策略模式
行为型设计模式之一,可以灵活的挑选不同的算法以实现某一问题
class HtmlParser implements Parser { public function export() { var_dump("export the markdown as html"); } } class PdfParser implements Parser { public function export() { var_dump("export the markdown as pdf"); } }
抽象产品角色 : 工厂创建产品的父类,封装了所有产品的公共接口,简化了工厂类中定义对象的类 型
客户端
产品抽象 类
具体产品角色:简单工厂模式的创建目标,需要实现抽象产品中定义的公共接口
01
工厂
实现对象创建和使用的分离,客户端不再关心对象的创建逻辑,工厂类包含了必 要的逻辑判断,决定何时创建哪一类产品
产品 A 产品 B
FileSessionHandler,DatabaseSessionHandler (store) …
oustn 2017
Usage
Auth::user(), Auth::guard(‘api’)->user() Broadcast::channel(), Broadcast::connection(‘redis’)->channel() Cache::get() Cache::driver(‘redis’)->get() DB::query() DB::connection(‘pgsql’)->query() Storage::put() Storage::disk(s3')->put() Mail::setSwiftMailer(app['swift.mailer']>driver(‘mandrill’)) Notification::send() Notification::driver(‘broadcast’)->send() Queue::push() Queue::connection(‘redis’)->push() Redis::set() Redis::connection('redis')->set() Session::all() Session::driver('file')->all()
Laraval
工厂模式的应用 及组件可扩展性探讨
Content
Laravel,设计模式,简单工厂模式,策略模式,扩展
简单的介绍两种简单的设计模式:简单工厂模式以及策 略模式,了解他们是为了解决何种问题而提出的,有哪 些优点和缺点。 接下来结合 Laravel 框架一起看看如何运用的,一些典 型的组件如何工作。 最后,学习 Laravel 中一些可扩展组件的做法,以及我 们自己如何很好的实践
OUSTN
oustn 2017
14
可扩展的组件
Markdown Parser Façade & extend
use Illuminate\Support\Facades\Facade; class MarkdownParser extends Facade { protected static function getFacadeAccessor() { return ParserManager::class; } } MarkdownParser::export();
创建策略基类
实现策略基类 Parser 定义的公共 接口 export()
创建实际的策略 类
创建 Html Parser 以 及 Pdf Parser,继承 自Parser,实现 export 接口,定义 具体的实现逻辑
创建Parser Manager
实现工厂方法,添加 默认 parser 创建规 则,添加创建 parser 接口,添加 __call 方法,实现消 息转发
设计模式
简单工厂模式 & 策略模式
Laravel 相关运用
Auth Manager,Cache Manager …
可扩展的组件
extend()
OUSTN
oustn 2017
2
简单工厂模式
创建型设计模式之一,定义一个工厂类,它可以根据参数的不同返回不同类的实例
工厂角色 : 简单工厂模式的核心,实现了创建所有产品实例的逻辑,提供静态工厂方法用于客户端 调用,返回产品类型
OUSTN
oustn 2017
13
可扩展的组件
Parser Manager
public function extend($name, \Closure $closure) { $this->customCreator[$name] = $closure; return $this; } private function createPdfParser() { return new PdfParser(); } private function createHtmlParser() { return new HtmlParser(); } public function __call($name, $arguments) { $this->parser()->$name($arguments); } }
Array Store
Memcache Store
Redis Store
Cache Manager
34%
Cache
OUSTN
oustn 2017
6
Laravel 中相关的组件
大概有 10 个组件都采用了这种方式
Facade Auth Broadcast Cache DB Storage
Manager AuthManager BroadcastManager CacheManager DatabaseManager FilesystemManager TransportManager
环境类:具体使用某种策略的角色,在环境类中维护了一个策略类的实例,用于定义采用的策略, 客户端直接调用该环境类,可以动态的切换不同的策略
抽象策略类:为所支持的算法声明了抽象方法,是所有策略类的父类,它可以是抽象类或具体类, 也可以是接口。环境类通过抽象策略类中声明的方法在运行时调用具体策略类中实现的算法。
客户端
环境类
策略抽象 类
具体策略类:实现了在抽象策略类中声明的算法,在运行时,具体策略类将覆盖在环境类中定义的 抽象策略类对象,使用一种具体的算法实现某个业务处理。
01
策略 A
策略 B
客户端在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法 或行为。
策略 C
02 03
通过依赖倒转,避免多重条件选择语句,把具体选择哪一种策略的逻辑与策略本 身区分开来,由客户端选择 提供算法的复用机制,讲算法单独提取出来放入到策略中,可以在不同的环境类 中复用这些算法
Strategy
TokenGuard, SessionGuard … PusherBroadcaster, RedisBroadcaster … RedisStore, FileStore …(Repository) MySqlConnection, PostgresConnection … Filesystem, Flysystem\Filesystem … MandrillTransport, MailgunTransport … DatabaseChannel, BroadcastChannel … RedisQueue, SqsQueue … PredisConnection, PhpRedisConnection …
Notification Queue Redis Session OUSTN
ChannelManager QueueManager RedisManager SessionManager
7
Cache 工作原理
Cache 中默认有 7 中 存储方式, Cache 是如何实现的呢
Stores 数组
储存 store 的实例,避免重复创建 store.
$arrayStore->get(‘key’)
createArrayDriver()
通过 Cache Manager 的创建实 例以及消息转发,达到调用实际 策略的作用
get(‘array’)
resolve(‘array’) 不同 driver 的 创建规则
OUSTN
oustn 2017
9
ຫໍສະໝຸດ Baidu 可扩展的组件
MarkdownParser::extend('image', function () { return new ImageParser(); })->parser('image')->export();
OUSTN
oustn 2017
15
Thanks for Watching
Cache 中默认有 7 中 存储方式, Cache 是如何实现的呢
__call(‘get’, ‘key’)
store()
getDefaultDriver()
Cache::get(‘key’)
Cache::store(‘redis’) ->get(‘key’)
通过 Cache Façade 调用 get 方 法获取某个缓存 key 的值
Store 的创建规则
每个类型的 store 对应一个相应的创建 规则,返回具体需要创建的产品
Store 接口
根据参数获取指定的 store 实例
__Call 魔术方法
通过魔术方法,把对 Cache manager 的调用转发到某个实际的 store 实例上
OUSTN
oustn 2017
8
Cache 工作原理
如何克服简单工厂模式的最大缺陷:无法动态添加产品创建规则
无法动态添加创建规则,如果要扩展,则需 要修改工厂类的代码
使用工厂方法模式,动态添加新的 工厂
Closure 闭包
OUSTN
oustn 2017
10
可扩展的组件
创建自己的可扩展组件
01
02
03
04
05
创建配置文件
创建 parse 配置文 件,定义默认的 parser,以及创建 parser 需要的一些 外部组件等等
OUSTN
oustn 2017
4
Laravel 中的运用
Laravel 很多组件都使用了这两种设计模式,来看看它是如何运用的
简单工厂模式


Manager
策略模式
-25


OUSTN
oustn 2017
5
Laravel 中相关的组件
大概有 10 个组件都采用了这种方式
相关组件
10
Database Store
添加 Facade
添加 Facade
OUSTN
oustn 2017
11
可扩展的组件
Config,Parser interface, Html Parser, Pdf Parser
return [ 'default' => env('MARKDOWN_PARSER', 'html') ]; interface Parser { public function export(); }
相关文档
最新文档