设计原则
面向对象的原则
单一职责
开闭原则
李氏替换原则(LSP): 门面的实现
依赖倒转原则(DIP): 服务指向契约, 契约绑定实现
接口隔离原则(ISP): 接口对应一种角色
最少知道原则: 类之间的弱耦合, 需要反复度量.
只和朋友交流 —
一个类只和朋友交流,不与陌生类交流,不要出现getA().getB().getC().getD()这种情况.除非每一个点后面返回类型都相同.朋友类的定义: 出现在成员变量 方法的输入输出参数中的类称为成员朋友类,而出现在方法体内部的类不属于朋友类.
朋友间也是有距离的 —
一个类公开的public属性或方法越多,修改时涉及的面积越大,变更引起的风险扩散也就越大.
迪米特法则要求类“羞涩”一点,尽量不要对外公布太多的public方法和非静态的public变量,尽量内敛,多使用private package-private protected等访问权限
是自己的就是自己的 —
如果一个方法放在本类中,即不增加类间的关系,也对本类不产生负面影响,就放置在本类中.
为什么要设计模式
设计模式是为了弥补语言的不足, 为了实现一些语言的特性
设计模式的分类
创建型模式:
single 单例
abstract factory
建造者模式
工厂模式
原型模式
结构型模式:
适配器模式
桥接模式
装饰模式
组合模式
外观模式
向元模式
代理模式
行为型模式:
模板方法模式
命令模式
迭代器模式
观察者模式
中介模式
laravel的设计模式
Facade(门面模式):
通过门面引入, 相比app函数引入的优点
IOC(控制反转)+DI(依赖注入):
不需要每次用的时候去new
Pipeline(管道模式)
做连贯操作后返回$this
Facade+IOC
https://github.com/masterzcw/componentized-tiny-laravel
管道模式
Linux的管道: 最基本的IPC机制, 进程间通信
Fork: fd[0] fd[1] 父进程与子进程通过pipe通信
概念: 将数据
interface Middleware
{
public static function handle(Closure $next);
}
class VerifyCsrfToken implements Middleware
{
public static function handle(Closure $next)
{
echo "VerifyCsrfToken --- 验证Csrf-Token"."<br/>";
$next();
}
}
class ShareErrorsFromSession implements Middleware
{
public static function handle(Closure $next)
{
echo "ShareErrorsFromSession --- 如果Session中有'errors'变量,则共享它"."<br/>";
$next();
}
}
class StartSession implements Middleware
{
public static function handle(Closure $next)
{
echo "StartSession --- 开启session,获取数据"."<br/>";
$next();
echo "StartSession ^^^ 保存数据,关闭session"."<br/>";
}
}
class AddQueuedCookiesToResponse implements Middleware
{
public static function handle(Closure $next)
{
$next();
echo "AddQueuedCookiesToResponse ^^^ 添加下一次请求需要的cookie"."<br/>";
}
}
class EncryptCookies implements Middleware
{
public static function handle(Closure $next)
{
echo "EncryptCookies --- 对输入的cookies进行解密"."<br/>";
$next();
echo "EncryptCookies ^^^ 对输出响应的cookie进行加密"."<br/>";
}
}
class CheckForMaintenanceMode implements Middleware
{
public static function handle(Closure $next)
{
echo "CheckForMaintenanceMode --- 确定当前程序是否处于维护状态"."<br/>";
$next();
}
}
/*
*函数getSlice()中的"()"需要留意。
*使用"function getSlice())"时,在array_reduce()中需要用“array($a,getSlice(),$b)”
*使用"function getSlice"时,在array_reduce()中需要用“array($a,"getSlice",$b)”。
*具体情况可以参考《Laravel框架关键技术解析---高清版.pdf》中“请求处理管道”一章
*/
function getSlice()
{
// 这一层: 作为array_reduce()的入参, $stack是每一次的callback
return function ($stack, $pipe) {
// 这一层: 被递归迭代的callback
return function () use ($stack, $pipe) {
return $pipe::handle($stack);
};
};
}
function then()
{
$pipes = [
CheckForMaintenanceMode::class,
EncryptCookies::class,
"AddQueuedCookiesToResponse",
StartSession::class,
"ShareErrorsFromSession",
VerifyCsrfToken::class,
];
$firstSlice = function () {
echo "请求向路由传递,返回响应"."<br/>";
};
$pipes = array_reverse($pipes); //把数组里的顺序颠倒一下,头变尾,尾变头
call_user_func(
array_reduce($pipes, getSlice(), $firstSlice)
// 把$pipes传入getSlice()里的$pipe,$firstSlice传入getSlice()里的$stack。且$firstSlice只传一次,$pipes数组每次传一个值,从尾部开始传,直到传完所有制为止。
);
}
then();