Laravel内核分析-设计模式--外观模式
概述
外观模式将一个系统中的每一项称为一个子系统,为这一组子系统提供一个高层接口,这个接口可以使得这一子系统更加容易被人使用。
通俗的来讲就是,将一系列的行为封装为一个接口,在这个接口中统一来调用这些行为
但是我们需要注意的是,并不是说,我们只对外暴露一个统一的接口,而细节要全部隐藏,
其实Facade只是为了方便一般用户调用,但是我们有特殊的需求需要访问某个或者某些个别子系统时,也可以自己通过调用各个子系统来完成自己的需求。
在Laravel 中我们常用到的 Route
、Redis
、Auth
这些 Facade 就是外观模式的具体实现,
在 Laravel 中设计了多个外观类,每个外观类继承自统一的抽象外观类,在抽象外观类里提供了通过外观类访问其背后子系统的基础方法。
对于新的业务需求,不要修改原有外观类,而应该增加一个新的具体外观类,
由新的具体外观类来关联新的子系统对象,同时通过修改配置文件来达到不修改源代码并更换外观类的目的。
模式结构
外观模式包含如下角色:
- Facade 外观角色
- SubSystem 子系统角色
Facade
- 知道哪些子系统类负责处理请求
- 将客户的请求代理给适当的子系统对象
SubSystem
- 实现了子系统的功能
- 处理由Facade对象指派的任务
- 不知道Facade的任何信息
代码示例
<?php
class Client
{
public function main()
{
//里面具体实现了什么我们不关心
(new Facade)->operation();
}
}
class Facade
{
private $systemA;
private $systemB;
public function __construct()
{
$this->systemA = new SystemA;
$this->systemB = new SystemB;
}
public function operation()
{
$this->systemA->operationA();
$this->systemB->operationB();
}
}
class SystemA
{
public function operationA()
{
//
}
}
class SystemB
{
public function operationB()
{
//
}
}
如果还是有疑惑,再来看一个例子
代码示例2
首先我们需要创建一些子系统来系统电脑的组装过程
以Cpu、Ram以及Rom来代表
CPU的处理
/**
* CPU的处理
*
* @author linrux </p>
*/
public class Cpu {
private String brand;
public Cpu(String brand) {
this.brand = brand;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public void assembly() {
System.out.println("组装Cpu: " + brand);
}
@Override
public String toString() {
return "Cpu{" +
"brand='" + brand + '\'' +
'}';
}
}
内存的处理
/**
* 内存的处理
*
* @author linrux</p>
*/
public class Ram {
private String brand;
public Ram(String brand) {
this.brand = brand;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public void assembly() {
System.out.println("组装内存: " + brand);
}
@Override
public String toString() {
return "Ram{" +
"brand='" + brand + '\'' +
'}';
}
}
硬盘的处理
/**
* 硬盘的处理
*
* @author linrux</p>
*/
public class Rom {
private String brand;
public Rom(String brand) {
this.brand = brand;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public void assembly() {
System.out.println("组装硬盘: " + brand);
}
@Override
public String toString() {
return "Rom{" +
"brand='" + brand + '\'' +
'}';
}
}
然后我们为这一子系统创建一个门面,来表示品牌的电脑整机替我们组装电脑的过程
/**
* 电脑整机
* @author linrux</p>
*/
public class CompleteMachine {
private Cpu cpu = new Cpu("酷睿i5");
private Ram ram = new Ram("金士顿16G");
private Rom rom = new Rom("金士顿1T");
public void install() {
cpu.assembly();
ram.assembly();
rom.assembly();
}
}
使用门面调用
/**
* 门面调用
*
* @author linrux
*/
public class MainTest {
public static void main(String[] args) {
CompleteMachine completeMachine = new CompleteMachine();
completeMachine.install();
}
}
运行结果如下:
组装Cpu: 酷睿i5
组装内存: 金士顿16G
组装硬盘: 金士顿1T
自己调用子系统
/**
* 自己调用子系统
*
* @author linrux
*/
public class MainTest {
public static void main(String[] args) {
Cpu cpu = new Cpu("酷睿i7");
Ram ram = new Ram("金士顿32G");
Rom rom = new Rom("金士顿2T SSD");
cpu.assembly();
ram.assembly();
rom.assembly();
}
}
运行结果如下:
组装Cpu: 酷睿i5
组装内存: 金士顿16G
组装硬盘: 金士顿1T
通过结果我们可以看到,在调用门面时,我们只需要通过门面给我们提供的方法就可以对整个子系统进行调用,非常方便。
而我们想要自己独特定制某些功能时,我们也可以手动的去调用各个子系统来完成我们的需求。放弃点性能还是很值得的
但是我想说的是,门面对类的访问在效率上还是比较低的,但是需要更好的维护,
版权声明:
作者:linrux
链接:https://www.tot7.cn/technology/laravel/429.html
来源:Code林
文章版权归作者所有,未经允许请勿转载。
共有 0 条评论