转载请注明来源
JANRS.COM - PHP Reflection 反射
#Example:
<?phpclass Foo {
private function myPrivateMethod() {
return 7;
}
}
$method = new ReflectionMethod('Foo', 'myPrivateMethod');
//该反射功能直接将原本是private权限的方法设置成可访问
$method->setAccessible(true);
echo $method->invoke(new Foo);// echos "7"?>
![JARNS.COM - 工厂模式[简单工厂UML图]](https://ucc.alicdn.com/pic/developer-ecology/18d3f91680fe464d9ab597877cd0edcd.jpg)
//生产抽象类abstract class Calculate{
//数字A
protected $number_a = null;
//数字B
protected $number_b = null;
//设置数字A
public function setNumberA( $number ){
$this->number_a = $number;
}
//设置数字B
public function setNumberB( $number ){
$this->number_b = $number;
}
//获取数字A
public function getNumberA(){
return $this->number_a;
}
//获取数字B
public function getNumberB(){
return $this->number_b;
}
//获取计算结果【获取生产出的产品】
public function getResult(){
return null;
}
}
//加法运算class CalculateAdd extends Calculate{
//获取运算结果【获取具体的产品】
public function getResult(){
return $this->number_a + $this->number_b;
}
}//减法运算class CalculateSub extends Calculate{
//获取运算结果【获取具体的产品】
public function getResult(){
return $this->number_a - $this->number_b;
}
}//乘法 / 除法 等等其他运算【其他产品】
//根据运算不同实例化不同的对象//【也就是根据所需产品,实例化对应的产品类进行生产】//对应的实现其实就是一个switch或者php8函数新出的match函数//下面用最新的match函数做演示class CalculateFactory{
public static function setCalculate( $type = null ){
return match( $type ){
'add' => (function(){
return new CalculateAdd();
})(),
'sub' => (function(){
return new CalculateSub();
})(),
default => null;
};
}
}
//具体使用
$calculate = CalculateFactory::setCalculate('add');
$calculate->setNumberA = 1;
$calculate->setNumberB = 2;
//计算echo $calculate->getResult;//echo 3
![JARNS.COM - 工厂模式[工厂UML图]](https://ucc.alicdn.com/pic/developer-ecology/10e3041e1ea84e96861fec8c75e4405c.jpg)
以下代码需要用到上面的生产抽象类:abstract class Calculate
以及具体的生产类,即:CalculateAdd 以及 CalculateSub。下面不再重复实现
interface CalculateFactory{
public function CreateCalculate();
}
class FactoryAdd implements CalculateFactory{
public function CreateCalculate(){
return new CalculateAdd();
}
}
class FactorySub implements CalculateFactory{
public function CreateCalculate(){
return new CalculateSub();
}
}
//具体使用
//创建工厂实例
$calculateFactory = new FactoryAdd();
$add = $calculateFactory->CreateCalculate();
$add->setNumberA( 1 );
$add->setNumberB( 2 );
//计算echo $add->getResult();//echo 3
![JARNS.COM - 抽象工厂模式[工厂UML图]](https://ucc.alicdn.com/pic/developer-ecology/2cf625ef6904443499f06db24188b5ca.jpg)
//抽象的产品类abstract class Phone{}abstract class System{}
//具体的产品类class IPhone extends Phone{}class MiPhone extends Phone{}
//具体的产品类class IOS extends System{}class Android extends System{}
//超级工厂interface AbstractFactory{
public function createPhone();
public function createSystem();
}
//具体的苹果工厂class iPhoneFactory implements AbstractFactory{
//生产苹果手机
public function createPhone(){
return new IPhone();
}
//生产苹果系统
public function createSystem(){
return new IOS();
}
}
//具体的小米工厂class MiFactory implements AbstractFactory{
//生产小米手机
public function createPhone(){
return new MiPhone();
}
//生产安卓系统
public function createSystem(){
return new Android();
}
}
· 一个抽象产品类(可以是:接口,抽象类,普通类),可以派生出多个具体产品类
· 单独一个具体的工厂类
· 每个具体工厂类只能创建一个具体产品类的实例
· 一个抽象产品类(可以是:接口,抽象类,普通类),可以派生出多个具体产品类
· 一个抽象工厂类(可以是:接口,抽象类),可以派生出多个具体工厂类
· 每个具体工厂类只能创建一个具体产品类的实例
· 多个抽象产品类(可以是:接口,抽象类,普通类),每个抽象产品类可以派生出多个具体产品类
· 一个抽象工厂类(可以是:接口,抽象类),可以派生出多个具体工厂类
· 每个具体工厂类可以创建多个具体产品类的实例
· 简单工厂模式只有一个抽象产品类,只有一个具体的工厂类
· 工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个抽象产品类
· 工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个具体产品类的实例
先看下以下的代码,需求背景:需要根据角色不同显示不同的权限按钮
<?php
class TaskController extends BaseController{
use HasResourceActions;
/**
* Make a grid builder.
*
* @return Grid
*/
protected function grid()
{
//Grid Columns...
if (Admin::user()->inRoles([AdminUserModel::getAssignmentRole()])) {
$grid->disableBatchActions();
$grid->disableEditButton();
$grid->disableCreateButton();
$grid->disableDeleteButton();
} elseif (Admin::user()->inRoles([AdminUserModel::getEvaluatorRole()])) {
$grid->disableBatchActions();
$grid->disableEditButton();
$grid->disableCreateButton();
$grid->disableDeleteButton();
$grid->actions(function (Grid\Displayers\Actions $actions) {
$actions->append(new ConfirmCloseTaskAction());
});
} else {
$grid->disableCreateButton();
$grid->disableDeleteButton();
$grid->disableEditButton();
$grid->disableBatchActions();
$grid->disableViewButton();
$grid->disableActions();
}
}
}
· 抽象出一个产品类来派生出多个角色的权限产品类
· 抽象出一个工厂类来派生出多个具体的工厂类,这些工厂类表现为对应要使用权限按钮的场景
· 每个具体工厂【使用权限按钮的场景】可以创建多个具体产品类【即实例化多个角色的权限产品】
<?php
namespace App\GridActionFactory;
use Dcat\Admin\Grid;
/**
* 工厂接口
*/interface GridActionInterface{
//业务员角色的权限
function salesmanAction(Grid $grid);
//分配员角色的权限
function assignmentAction(Grid $grid);
//财务角色的权限
function financeAction(Grid $grid);
//....其他角色的权限
}
<?php
namespace App\GridActionFactory;
use Dcat\Admin\Admin;use Dcat\Admin\Grid;
/**
* 设置Action权限抽象类
*/abstract class GridActionAbstract{
//
abstract public static function setAction(Grid $grid, string $role);
/**
* 过滤角色
*
* @param string $role
* @return bool
*/
protected static function isInRoles(string $role): bool
{
return Admin::user()->inRoles([$role]);
}
/**
* 调用对应的方法
* [该方法其实就是工厂模式中的工厂,专门来生产的]
* [多个工厂对应的就是各个需要用到Action权限的Controller控制器]
* [每个Controller控制器来生产自己的Action权限]
* [这个生产是通过反射来实现]
*
* @param Grid $grid
* @param string $role
* @param string $class
* @throws \ReflectionException
*/
protected static function setRoleAction(Grid $grid, string $role, string $class)
{
$r = new \ReflectionClass($class);
$methodName = $role . 'Action';
if (!$r->hasMethod($methodName))
throw new \Exception('Method Not Found [ method : ' . $methodName . ' ] ');
$method = $r->getMethod($methodName);
$method->invoke($r->newInstance(), $grid);
}
}
<?php
namespace App\GridActionFactory;
use Dcat\Admin\Grid;
class TaskAction extends GridActionAbstract implements GridActionInterface{
/**
* @param Grid $grid
* @param string $role
* @throws \ReflectionException
*/
public static function setAction(Grid $grid, string $role)
{
if (!parent::isInRoles($role)) return;
//通过调用父类的setRoleAction直接实现生产的过程
parent::setRoleAction($grid, $role, self::class);
}
//在TaskController下有需要使用权限按钮的角色
//分配员角色
public function assignmentAction(Grid $grid)
{
//权限按钮
$grid->showActions();
$grid->showViewButton();
}
//在TaskController下有需要使用权限按钮的角色
//财务角色
public function financeAction(Grid $grid)
{
$grid->showActions();
$grid->showViewButton();
}
//在TaskController下有需要使用权限按钮的角色
//业务员角色
public function salesmanAction(Grid $grid)
{
}
//....其他角色
}
<?php
class TaskController extends BaseController{
use HasResourceActions;
/**
* Make a grid builder.
*
* @return Grid
*/
protected function grid()
{
//Grid Columns...
//财务角色按钮
TaskAction::setAction($grid, AdminUserModel::getFinanceRole());
//分配员角色按钮
TaskAction::setAction($grid, AdminUserModel::getAssignmentRole());
//...其他角色按钮
/*
if (Admin::user()->inRoles([AdminUserModel::getAssignmentRole()])) {
$grid->disableBatchActions();
$grid->disableEditButton();
$grid->disableCreateButton();
$grid->disableDeleteButton();
} elseif (Admin::user()->inRoles([AdminUserModel::getEvaluatorRole()])) {
$grid->disableBatchActions();
$grid->disableEditButton();
$grid->disableCreateButton();
$grid->disableDeleteButton();
$grid->actions(function (Grid\Displayers\Actions $actions) {
$actions->append(new ConfirmCloseTaskAction());
});
} else {
$grid->disableCreateButton();
$grid->disableDeleteButton();
$grid->disableEditButton();
$grid->disableBatchActions();
$grid->disableViewButton();
$grid->disableActions();
}
*/
}
}
版权声明:本文内容转发自阿里云社区,由阿里云实名注册用户自发贡献!版权归原作者所有。本站不拥有其著作权,亦不承担相应法律责任。如果您发现本文中有涉嫌抄袭的内容,请联系站内客服,本站将立刻删除涉嫌侵权内容。