Принцип разделения сечений - тип, намекающий на несколько интерфейсов

Вопрос о титровании интерфейсов ролей .

Пример кода имеет два DataMappers, которые набирают интерфейс, который им нужен в конструкторе,

Тип FooDataMapper подсказывает готовый интерфейс. Потому что это зависит от него и от другого не зависит от другого.

В другом сопоставлении, BarDataMapper i заменил тип подсказки на ??? поскольку для этого требуются как подготовимый, так и запрошенный интерфейс.

Как я могу справиться с этим (что следует заменить ???), typehinting одного из них не хватит, должен ли я создать новый интерфейс (возможно, тот, который расширяет предыдущие) и намекнуть на этот новый интерфейс?

Пример кода - это сложенный пример в PHP, а тип hint (???) - в объявленном последнем классе.

<?php
// TWO ROLE INTERFACES, SMALL SEGREGATED PART OF A DBAL

Interface Preparable {
  public function prepare( .. );
}

Interface Queryable {
  public function query( ... );
}


// ADAPTER IMPLEMENTS SEGREGATION

class DbalAdapter implements Preparable, Queryable {
  private $dbal;

  public function __construct($dbal) 
  {
    private $this->dbal = $dbal;
  }

  public function prepare( .. ) 
  {
    ..
    return $this->dbal->prepare( .. );
  }

  public function query( .. ) 
  {
    ..
    return $this->dbal->query( .. );
  }
}


// DATAMAPPER CTOR HINTS FOR METHODS IT NEEDS TO USE

class FooDataMapper implements DataMapper {
  private $dbal;

  public function __construct(Preparable $dbal)
  {
    $this->dbal = $dbal;
  }

  public function create(Foo $Foo) 
  {
    ..
    $this->dbal->prepare( .. )
  }
}


// DATAMAPPER CTOR HINTS FOR METHODS IT NEEDS TO USE
// BUT THIS TIME NONE OF THE ROLE INTERFACES MATCH, BUILD A NEW INTERFACE?

class BarDataMapper implements DataMapper {
  private $dbal;
  public function __construct(??? $dbal) 
  {
    $this->dbal = $dbal;
  }

  public function SomeMethodThatNeedsBothPrepareNQuery(Bar $Bar) 
  {
    ..
    $this->dbal->query( .. )
    $this->dbal->prepare( .. )
  }
}

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

Остерегайтесь, что имена классов в коде только для показа, возможно, также были Fooable, BarAble ...

1 голос | спросил Ronni Skansing 28 Jam1000000amTue, 28 Jan 2014 04:08:17 +040014 2014, 04:08:17

2 ответа


2

потребитель зависимостей - это тот, кто отвечает за их определение (посредством своих интерфейсов). В вашем примере правила BarDataMapper. Я вижу два возможных сценария:

  1. Если BarDataMapper зависит от одного объекта, реализующего как prepare() и query(), затем да , правильный PreparableAndQueryable должен быть определен, включая два из них, и передаваться конструктору. Но тогда, возможно, вы захотите найти другое содержательное, несозданное имя, не намекающее на плохое разделение проблем.

  2. Если для BarDataMapper имеет смысл использовать независимый Preparable и Queryable, то его конструктор принимает их как отдельные параметры, даже если в конце есть действительно один объект, реализующий оба интерфейса . Кто действительно реализует интерфейсы, не должен беспокоить тех, кто их потребляет.

ответил rucamzu 30 Jam1000000amThu, 30 Jan 2014 02:06:33 +040014 2014, 02:06:33
1

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

В соответствии с принципом сегрегации интерфейса интерфейс DataMapper должен быть достаточно строгим, чтобы вы могли установить один интерфейс, а один из них должен был соответствовать всем вашим реализациям DataMappers. Эта реализация не должна ожидать более специализированного объекта.

Одно из возможных решений для вашей проблемы использования двух интерфейсов в одно и то же время, вы можете использовать черты с абстрактными методами (if> = PHP 5.4) вместо интерфейса. Но я бы этого не сделал, так как он пытается имитировать «наследование интерфейса», используя возможности компоновки черт.

Если какой вы хотите, это предложение в вашей среде IDE, вам не нужно использовать подсказки типа (это то, что вы делаете). Вы можете использовать PHPDoc, и ваша среда IDE может распознать, что вы делаете (я рекомендую PhpStorm):

/**
  * @param MySuperClass $a
  * @return void 
  */
public function myFunction($a) {
    // Here your IDE will know what kind of object is $a
}

Последнее: не пытайтесь делать Java с PHP. В какой-то момент, если вы хотите обеспечить, что предоставленный объект, вы можете использовать быструю интроспекцию, чтобы проверить правильное использование правильных классов, подклассов, признаков и интерфейса.

ответил AsTeR 30 Jam1000000amThu, 30 Jan 2014 01:53:40 +040014 2014, 01:53:40

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132