深入 Laravel 内核之装饰模式
装饰模式核心内容:
- 装饰模式可以在不影响组件对象的情况下,以动态、透明的方式从外部给对象添加功能;
- 装饰器模式的本质就是动态组合。动态是手段,组合是目的。装饰模式是通过把复杂的功能简单化、分散化,在运行期间,根据需要来动态组合出需要的功能;
- 使用不同的装饰类以及这些装饰类的排列组合,可以创造出很多不同功能的对象。可以使用多个装饰类来装饰同一对象,创造功能更为强大的对象;
- 装饰抽象类的接口必须与组件抽象类的接口相同,对于客户端来说无论是装饰之前的对象还是装饰之后的对象都可以使用同样的方式调用;
- 组件实现类 ConcreteComponent 应该尽量保持简洁和轻量,不要把主逻辑之外的辅助逻辑和状态放在组件实现类中,应该通过装饰类对其进行扩展。
定义一个组件抽象类:
abstract class Component
{
abstract public function operation();
}
定义一个组件实现类,实现组件功能:
class ConcreteComponent extends Component
{
public function operation()
{
echo __CLASS__ . '|' . __METHOD__ . "\r\n";
}
}
定义一个装饰器抽象类,接口与组件类一致:
abstract class Decorator extends Component
{
/**
* 持有Component对象,该对象就是被装饰的对象
*/
protected $component;
/**
* 构造方法传入
* @param Component $component
*/
public function __construct(Component $component)
{
$this->component = $component;
}
abstract public function operation();
}
定义两个装饰器,用来扩展原有组件的功能,或者实现新的功能:
class ConcreteDecoratorA extends Decorator
{
public function beforeOperation()
{
echo __CLASS__ . '|' . __METHOD__ . "\r\n";
}
public function afterOperation()
{
echo __CLASS__ . '|' . __METHOD__ . "\r\n";
}
public function operation()
{
$this->beforeOperation();
//这里可以调用父类的方法,也可以不调用直接改写实现新功能
$this->component->operation();
$this->afterOperation();
}
}
class ConcreteDecoratorB extends Decorator
{
public function beforeOperation()
{
echo __CLASS__ . '|' . __METHOD__ . "\r\n";
}
public function afterOperation()
{
echo __CLASS__ . '|' . __METHOD__ . "\r\n";
}
public function operation()
{
$this->beforeOperation();
//这里可以调用父类的方法,也可以不调用直接改写实现新功能
$this->component->operation();
$this->afterOperation();
}
}
客户端使用示例:
class Client
{
public function main()
{
$component = new ConcreteComponent();
echo "\r\n直接使用组件:\r\n";
$component->operation();
$decoratorA = new ConcreteDecoratorA($component);
echo "\r\n使用装饰器A装饰后的组件:\r\n";
$decoratorA->operation();
$decoratorB = new ConcreteDecoratorB($decoratorA);
echo "\r\n使用装饰器A和B装饰后的组件:\r\n";
$decoratorB->operation();
}
}
$client = new Client();
$client->main();
深入 Laravel 内核之装饰模式的更多相关文章
- 深入 Laravel 内核之观察者模式
装饰模式核心内容: 观察者模式又称为发布订阅模式,定义了对象间的一对多依赖关系,当一个对象状态发生改变时,其相关依赖的其他对象都能接收到通知: 观察者模式的核心在于目标(Subject)和观察者(Ob ...
- 深入 Laravel 内核之IOC容器
升级工厂前的准备工作 无规矩不成方圆,随着越来越多的行为出现,我们需要需要定下一些规范. 为了约束每一个行为的规范,需要定义一个行为接口: interface BehaviorInterface { ...
- 深入 Laravel 内核之工厂模式
英雄与行为,依赖的诞生 首先定义一个英雄,英雄具有一些行为: class Hero { protected $behavior = []; public function show() { var_d ...
- 深入 Laravel 内核之外观模式(门面模式)
门面模式核心内容: 客户端与子系统的通信通过外观对象进行: 外观对象封装一系列子系统的具体对应方法,对客户端只需暴露一个单一的入口方法: 客户端通过访问外观对象即可调用子系统的基础方法,无需关心子系统 ...
- 深入 Laravel 内核之 PHP 反射机制和依赖注入
结论: PHP中提供了反射类来解析类的结构: 通过反射类可以获取到类的构造函数及其参数和依赖: 给构造函数的参数递归设置默认值后,即可使用这些带默认值的参数通过 newInstanceArgs 实例化 ...
- laravel 实现思路以及各组件原理
laravel 内核是个IOC容器,IOC是把本来自己实例化的对象. 通过在容器里注册,通过容器来进行实例化. laravel队列用的是redis的列表来实现.
- Laravel源码解析之从入口开始
前言 提升能力的方法并非使用更多工具,而是解刨自己所使用的工具.今天我们从Laravel启动的第一步开始讲起. 入口文件 laravel是单入口框架,所有请求必将经过index.php define( ...
- Laravel核心解读--Contracts契约
Contracts Laravel 的契约是一组定义框架提供的核心服务的接口, 例如我们在介绍用户认证的章节中到的用户看守器契约IllumninateContractsAuthGuard 和用户提供器 ...
- LaravelS - 基于Swoole加速Laravel/Lumen
LaravelS LaravelS是一个胶水项目,用于快速集成Swoole到Laravel或Lumen,然后赋予它们更好的性能.更多可能性.Github 特性 内置Http/WebSocket服务器 ...
随机推荐
- OC-私有方法,构造方法,类的本质及启动过程
总结 标号 主题 内容 一 OC的私有方法 私有变量/私有方法 二 @property 概念/基本使用/寻找方法的过程/查找顺序 三 @synthesize @synthesize概念/基本使用/注意 ...
- 【Java基础】Java 注解详解
对于Java注解,我之前的印象是很模糊的,总觉得这个东西经常听说,也经常用,但是具体是怎么回事,好像没有仔细学习过,说到注解,立马想到@Controller,仅此而已. 对于Java注解,我咨询过一些 ...
- grep命令输出显示高亮字
grep命令执行后,终端上输出显示颜色可以加"--color=auto"的参数. 另外的两个办法是: 1.设置环境变量: export GREP_OPTIONS="--c ...
- MyBatis一对多映射简单查询案例(嵌套结果)
一.案例描述 书本类别表和书本信息表,查询书本类别表中的某一记录,连带查询出所有该类别书本的信息. 二.数据库表格 书本类别表(booktypeid,booktypename) 书本信息表(booki ...
- TV盒子 android 4.4安装kodi 和 安装jellyfin插件连接到 jellyfin服务器
很多IPTV盒子系统都是android 4.4的,无法安装新版kodi, 最高只能安装到改版的kodi, 版本是17.1,jellyfin插件也只能安装到0.5.8 首先下载kodi和jellyfin ...
- centos源码安装ruby
目录 一.简介 二.程序部署 一.简介 Ruby,一种简单快捷的面向对象(面向对象程序设计)脚本语言.rvm是ruby的管理器,可以切换ruby版本,下载ruby. 二.程序部署 1.下载ruby w ...
- 搭建 3D 智慧农场可视化,解锁绿色生态田园
前言 何为"无人农场"?中国工程院院士罗锡文用五句话高度概括:"耕种管收生产环节全覆盖:机库田间转移作业全自动:自动避障异况停车保安全:作物生产过程实施全监控:智能决策精 ...
- 使用.NET 6开发TodoList应用(5.1)——实现Repository模式
需求 经常写CRUD程序的小伙伴们可能都经历过定义很多Repository接口,分别做对应的实现,依赖注入并使用的场景.有的时候会发现,很多分散的XXXXRepository的逻辑都是基本一致的,于是 ...
- Spring Boot程序插入时间和MySQL数据库显示时间不一样(设置数据库时区)
首先查看数据库时区 show variables like "%time_zone%"; # 设置全局时区 mysql> set global time_zone = '+8 ...
- 二叉搜索树判定方法(c++实现)
!!版权声明:本文为博主原创文章,版权归原文作者和博客园共有,谢绝任何形式的 转载!! 作者:mohist --- 欢迎指正--- 自己想到的方法是:使用 中序遍历数组或者链表,然后比较数组或者链表中 ...