2013-12-06 3 views
3

Я, вероятно, не понимаю чего-то очень простого.Интерфейсы и аутсорсинг

Тим делает гипотетическое приложение, которое использует сеансы, он ленив и хочет использовать существующие решения вместо того, чтобы создавать свои собственные. Он обнаруживает 2 разработчиков, Джона и Фабьен, которые имеют exacly, что ему нужно (но не знают о существовании друг друга):

Фабьен, который создал 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){ 
     ... 
    } 
} 

и Иоанн, почитаемые создано: 1 класс и 1 интерфейс, соответствующий интерфейс, созданный Фабьен

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

Тим считает, что класс Джона хранения значительно превосходит тот, сделанные Фабьен и хочет использовать его с классом Session

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

Но это не сработает, поскольку класс Session Fabiens принимает только классы, которые реализуют Fabien \ SessionStorageInterface.

Как Тим может использовать класс Session, предоставленный Fabien, в сочетании с классом хранения, созданным Джоном?

+0

Это будет работать, если класс Session не используется тип намекая. – bitWorking

+0

@redreggae Конструкция класса Session частично основана на структуре в symfony, и, к сожалению, она использует тип намека. –

+0

Это действительно читается как домашнее задание –

ответ

0

Это не так.

Как и в большинстве других языков программирования, им приходится реализовывать один и тот же интерфейс (то же самое! == такая же подпись).

Они также изучают правила одного класса/интерфейса для каждого файла, чтобы облегчить задачу для кого-то, кто хотел бы что-то взломать из своего кода.

+0

Я пропустил один класс для правила файла для упрощения примера, поскольку он не связан с вопросом –

+0

Извините, я сформулировал свою идею плохо. Идея состоит в том, чтобы сделать жизнь легкой для кого-то, взломав свой код. –

+0

как это отвечает на вопрос? –

1

Вы можете поместить немного клеевого кода между двумя интерфейсами/реализациями.
Определите класс, который реализует интерфейс (A), который вам нужен, но внутренне делегирует вызовы методов экземпляру класса (B), который вы хотите. Таким образом, ваш посредническую adapter экземпляр является Л, но имеет в 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(); 
} 
+0

Отличная идея! Единственный недостаток, который я могу себе представить, - это напечатать все функции, если их много. Постскриптум Насколько мне известно, ваш класс «посредник» использует шаблон «декоратор». –

+2

@TimoHuovinen Я думаю, что это больше похоже на [адаптер] (https://en.wikipedia.org/wiki/Adapter_pattern). – Yoshi

+1

Адаптер звучит правильно, обновляя ответ .... – VolkerK

Смежные вопросы