diffnest / myblog

0 stars 0 forks source link

门面模式怎么用??? #18

Open diffnest opened 6 years ago

diffnest commented 6 years ago

最近在开发api接口,频频用到了需要调用不同class里面的不同方法,这个时候在想,是否可以把子系统所有用到的类做成一个集合,然后通过一个统一的对象来进行通信呢,这时候想到了门面模式,下面简单归纳总结下门面模式;

  1. 定义:门面模式Facade Pattern也叫外观模式,要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行,门面模式提供一个高层次的接口,使得子系统更容易使用,将所有从客户端发来的请求委派到相应的子系统去,也就是说该角色没有实际的业务逻辑,仅仅是一个委托类,说到底门面模式就是把几个子系统(实例或者类.统一一个统一的接口进行执行,客户端不用关注子系统)

  2. 角色组成:
    1.此角色将被客户端调用
    2.知道哪些子系统负责处理请求
    3.将用户的请求指派给适当的子系统

  3. 子系统(subsystem)角色
    1.实现子系统的功能
    2.处理由Facade对象指派的任务
    3.没有Facade的相关信息,可以被客户端直接调用
    4 可以同时有一个或多个子系统,每个子系统都不是一个单独的类,而一个类的集合。每个子系统都可以被客户端直接调用,或者被门面角色调

  4. 实例DEMO

class CPU 
{
    public function freeze() {
        echo "Freeze the CPU\n";
    }
    public function jump($address) {
        echo "Jump to $address\n";
    }
    public function execute() {
        echo "Execute\n";
    }
}
class Memory 
{
    public function load($address, $data) {
        echo "Loading address $address with data: $data\n";
    }
}
class Disk 
{
    public function read($sector, $size) {
        return "data from sector $sector ($size)";
    }
}

// Facade
class Computer 
{
    const BOOT_ADDRESS = 0;
    const BOOT_SECTOR = 1;
    const SECTOR_SIZE = 16;
    protected $cpu;
    protected $mem;
    protected $hd;

    public function __construct(CPU $cpu, Memory $mem, Disk $hd) {
        $this->cpu = $cpu;
        $this->mem = $mem;
        $this->hd  = $hd;
    }

    public function startComputer() {
        $this->cpu->freeze();
        $this->mem->load(self::BOOT_ADDRESS, $this->hd->read(self::BOOT_SECTOR, self::SECTOR_SIZE));
        $this->cpu->jump(self::BOOT_ADDRESS);
        $this->cpu->execute();
    }
}
// Usage example
$pc = new Computer(new CPU, new Memory, new Disk);
$pc->startComputer();

5 API实例

//服务提供者(类)
class ServiceProvider
{
    public function Write($arg) {
        echo $arg;
    }
}

//门面
class Facade
{
    public static function getInstance($classname,$args) {

        return new $classname($args);
    }

    public static function getFacadeAccessor() {
        //
    }

    public static function __callstatic($method,$args) {

        $instance=static::getInstance(static::getFacadeAccessor(),$args);

        return call_user_func_array(array($instance,$method),$args);
    }
}

class MyFacade extends Facade
{
    public static function getFacadeAccessor() {
        echo ServiceProvider::class;
    }
}
//具体调用
MyFacade::Write(123);