2013-11-11 3 views
0

Это может быть глупый вопрос. Я пытаюсь создать универсальный интерфейс хранилища для Doctrine 2, так что я могу передать его в мой контроллер путем прямого впрыска:PHP/Doctrine2 - Внедрить интерфейс дважды

//TestController.php 

public function __construct(TestRepositoryInterface $p_repository){ 
    //... 
} 

Метод подписи для EntityRepository в Doctrine2 выглядит следующим образом:

class EntityRepository implements ObjectRepository, Selectable{ 
    //... 
} 

EntityRepository не хватает нескольких функций, которые я хотел бы иметь в репозитории (Добавить, Удалить, Обновить). Таким образом, я создал интерфейс базового хранилища и абстрактный класс хранилища для инкапсуляции этих функций:

interface RepositoryInterface { 
    public function add($entity); 
    public function delete($entity); 
    public function update($entity); 
} 

Абстрактный класс хранилище простирается от EntityRepository, так что я могу еще получить функциональные возможности EntityRepository.

abstract class AbstractRepository extends EntityRepository{ 
    public function add($entity){ 
     //... 
    } 

    public function add($entity){ 
     //... 
    } 

    public function add($entity){ 
     //... 
    } 
} 

Для того, чтобы связать все вместе, я сделал TestRepositoryInterface простираться от RepositoryInterface, ObjectRepository и Selectable.

interface TestRepositoryInterface extends RepositoryInterface, ObjectRepository, Selectable{ 

} 

Тогда я могу просто пройти в реализации TestRepositoryInterface путем прямого впрыска:

class TestImplementation extends AbstractRepository implements TestRepositoryInterface{ 
    //... 
} 

Или если я модульное тестирование, было бы легко создать макет объекта или тест-заглушки.

Моя единственная забота в категории TestImplementation. Это расширяет AbstractRepository, который уже реализует ObjectRepository и Selectable (через EntityRepository), и в то же время TestImplementation также реализует TestRepositoryInterface, который также расширяет ObjectRepository и Selectable. Таким образом, TestImplementation по существу реализует ObjectRepository и Selectable дважды (или это?). Он компилируется просто отлично, но действительно ли это правильный подход?

ответ

0

Совершенно нормально для класса, реализующего несколько интерфейсов, которые, в свою очередь, расширяют общие интерфейсы. Методы одинаковы, поэтому конфликтов нет.

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

Скажем, у вас есть интерфейс, реализация которого требует повторения. Вероятно, у вас есть его реализация \IteratorAggregate.

Теперь скажем, что ваш класс реализации расширяет ArrayCollection (из общей доктрины). Поскольку ArrayCollection также реализует IteratorAggregate, он позаботится о некоторых определениях вашего собственного интерфейса.

Когда речь заходит о смешивании интерфейсов, ищите проблемы с совместимостью, а не с наследованием.

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