接口和外包

时间:2013-12-06 09:00:12

标签: php class interface

我可能听不懂非常基本的东西。

Tim正在制作一个使用Sessions的假设应用程序,他很懒,想要使用现有的解决方案而不是制作自己的解决方案。 他发现了两个开发人员John和Fabien,他们非常需要(但彼此不了解):

Fabien,他创建了2个类和1个接口

namespace Fabien;
interface SessionStorageInterface {
   public function set($key, $val); 
   public function get($key);
}
class Storage implements SessionStorageInterface {
   ...
}
class Session {
    public function __construct(SessionStorageInterface $storage){
        ...
    }
}

John,他创建了1个类和1个接口,与Fabien创建的接口相匹配

namespace John;
interface SessionStorageInterface {
   public function set($key, $val); 
   public function get($key);
}
class Storage implements SessionStorageInterface {
   ...
}
Tim认为John的存储类远远优于Fabien制作的类,并希望将它与Session类一起使用

$storage = new John\Storage;
$session = new Fabien\Session($storage);

但这不起作用,因为Fabiens Session类只接受实现Fabien \ SessionStorageInterface的类。

Tim如何将Fabien提供的Session类与John创建的Storage类结合使用?

2 个答案:

答案 0 :(得分:1)

您可以在两个接口/实现之间添加一些胶水代码 定义一个实现您需要的接口(A)的类,但在内部将方法调用委托给您想要的类(B)的实例。因此,您的中介adapter实例 A,但 是B。

<?php
namespace Fabien {
    interface SessionStorageInterface {
       public function set($key, $val); 
       public function get($key);
    }

    class Storage implements SessionStorageInterface {
        public function set($key, $val) { 
            echo 'enter ', __METHOD__, "\r\n";
            $this->stg[$key] = $val;
        }
        public function get($key) {
            echo 'enter ', __METHOD__, "\r\n";
            return $this->stg[$key];
        }
    }

    class Session {
        public function __construct(SessionStorageInterface $storage){
            echo 'enter ', __METHOD__, "\r\n";
            $storage->set('foo', 'bar');
            echo 'foo=', $storage->get('foo'), "\r\n";
        }
    }
}


namespace John {
    interface SessionStorageInterface {
       public function set($key, $val); 
       public function get($key);
    }
    class Storage implements SessionStorageInterface {
      public function set($key, $val) { 
            echo 'enter ', __METHOD__, "\r\n";
            $this->stg[$key] = $val;
        }
        public function get($key) {
            echo 'enter ', __METHOD__, "\r\n";
            return $this->stg[$key];
        } 
    }
}

namespace Demo {
    class StorageAdapter implements \Fabien\SessionStorageInterface {
        protected $storageJohn = null;

        public function __construct(\John\SessionStorageInterface $stg) {
            $this->storageJohn = $stg;
        }

        public function set($key, $val) { 
            echo 'enter ', __METHOD__, "\r\n";
            $this->storageJohn->set($key, $val);
        }

        public function get($key) {
            echo 'enter ', __METHOD__, "\r\n";
            $this->storageJohn->get($key);
        } 

    }


    function demo() {
        echo 'enter ', __METHOD__, "\r\n";
        $stg = new \John\Storage;
        $session = new \Fabien\Session( new StorageAdapter($stg) );
    }
    demo();
}

答案 1 :(得分:0)

他们没有。

与大多数其他编程语言一样,他们必须实现相同的接口(相同的!==相同的签名)。

他们还学习了每个文件规则的一个类/接口,以便让那些想要破解代码内容的人轻松上手。