Разные интерфейсы, одинаковые методы

AmdY

Пью пиво
Команда форума
Более широкий вариант: есть два пакета функций, которые требуют два разных контракта, каждый из которых определяет по методу с идентичными сигнатурами, нужно одну сущность (одну реализацию, одну алгебру) заставить работать синхронизировано в разных аспектах.
Отличная демонстрация, почему в php нафик не сдалась перегрузка функций. Из-за экономии на названии возникает пятистраничный тред.

 

WMix

герр M:)ller
Партнер клуба
Lionishy, а можешь написать, плиз, полностью рабочий c++ код с main методом, чтоб только команду на компиляцию нужно было отдать? (желательно с учетом того о чем ты говорил, не 2 метода а один и тотже (сигнатура) 2 раза)
...
void Resolver::resolveDog()
{
std::cout << "I'm a DOG resolved by Resolver" << std::endl;
}
[/CODE]
 

WMix

герр M:)ller
Партнер клуба
Lionishy, мне не нужны слова, мне хочется увидеть на плюсах то что у тебя не получается на пхп, при этом я хочу видеть все вызовы в одном месте, в маин. так ты мне сможешь обьяснить смысл твоей реализации, почему ты хочешь так а не иначе. (своего рода юниты)
словами у тебя не получается! тебя кидает то на марсы то к собакам теперь на пакеты и контракты.
 

Lionishy

Новичок
WMix, я честно пытаюсь подобрать слова, которые бы Вы поняли. Или примеры, которые бы вы прочитать смогли.
почему ты хочешь так а не иначе
Потому что в моём проекте сущность одновременно является и IResolveCat сущностью, и IResolveDog сущностью. Это одни и те же данные, одна и та же внутренняя структура, но она может быть представлена разными гранями для двух разных аспектов работы системы. Очевидным (полагаю для большинства вменяемых проектировщиков) решением является создание класса, который будет реализовывать два интерфейса (создание реализации, которая будет поддерживать оба контракта). Однако так получилось, по независящим от меня лично причинам, что IResolveCat и IResolveDog имеют по одному методу с одинаковой сигнатурой.
Я знаю точно как обойти это в С++ (ровно, как написано в моём примере), я знаю, как бы можно было это обойти в C#. А что можно сделать в PHP? Как поступить если нужно в одном классе реализовать два интерфейса, которые определяют каждый по методу с одинаковой сигнатурой?

В моём примере resolveCat() не является частью открытого интерфейса. Это как раз та самая "внутренняя реализация". Клиентам моего Resolver она не видна. Специально во втором примере отметил как protected. Виден только метод resolve. Точнее два метода resolve: IResolveCat::resolve и IResolveDog::resolve. Как и требовалось.


AmdY, больше кода! Пока есть те, кто "пишут б***ть!" У меня будет халтурка =)
 

Lionishy

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

AmdY

Пью пиво
Команда форума
Lionishy, надо давать разные названия методам, а не называть детей одним именем "Саша", а потом различать на основании мальчик это или девочка. То что другие некоторые языки позволяют так делать, это не значит что так лучше.
для интерфейсов нужно мутить разные имена, а вот для трейтов есть костыль,
PHP:
use A, B {
        B::smallTalk insteadof A;
        A::bigTalk insteadof B;
    }
 

WMix

герр M:)ller
Партнер клуба
Lionishy, еще раз, каков смысл от твоих интерфейсов если они используются ТОЛЬКО внутри? ты можешь использовать снаружи в main то что ты хочешь или будешь дальше сиси мять?
Потому что в моём проекте сущность одновременно является и IResolveCat сущностью, и IResolveDog сущностью.
у меня тоже!
Я знаю точно как обойти это в С++
это и есть ключевой момент, показывай!
 

Lionishy

Новичок
AmdY, надо давать разные названия методам, а не называть детей одним именем "Саша".
Разные родители вполне могут назвать своих детей Сашами.
Я помню в 11м классе у нас училось одновременно пять Алексеев.
Если интерфейс называется ICatResolver, то дублировать его название в методе -- не комильфо. Это всё равно, что комментировать операцию инкремента.
Вы же не будете дублировать в названии класса типы всех его композитных элементов, предков и пространство имён.

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

WMix,
используются ТОЛЬКО внутри
Что значит "используются внутри"?
Используются внутри пакетов vendor1 и vendorB? Смысл огромный! Поставщики определяют контракт, чтобы в их структуру не попадало всякое разное, а попадало только то, с чем они умеют работать.

это и есть ключевой момент, показывай!
Всё уже показано. Проблемная ситуация в том, что Вы отказываетесь это понимать.
 

Redjik

Джедай-мастер
Используются внутри пакетов vendor1 и vendorB? Смысл огромный! Поставщики определяют контракт, чтобы в их структуру не попадало всякое разное, а попадало только то, с чем они умеют работать.
крнтрак определяется АПИ => публичными методами => интерфейсом

у WMix, - интерфейс идентичен твоему примеру на С++
классный тебе нужен интерфейс с реализацией...
хорошо, что из-за таких архитекторов у нас работа есть.
 

Lionishy

Новичок
Redjik,
крнтрак определяется АПИ => публичными методами
Да, но разные производители не обязаны предоставлять Вам интерфейсы с методами, которые отличны друг от друга.
Именно такой случай и обсуждается с самой первой страницы.

Пример WMix вообще далёк от проблемной ситуации.
Даже в этой теме есть примеры, в которых люди сосредоточили своё внимание именно на проблеме, конкретной, а не на собственных иллюзиях, что сложные задачи можно решить просто, а виноваты во всём кривые проектировщики.
 

WMix

герр M:)ller
Партнер клуба
Поставщики определяют контракт, чтобы в их структуру не попадало всякое разное, а попадало только то, с чем они умеют работать.
вот этот кусок и покажи снаружи. как они используют этот интерфейс. 3 строки, не новую, а старую задачу, как оно работает?
 

Lionishy

Новичок
WMix,
Код:
void vendor1::explain(IResolveCat& resolver)
{
    resolver.resolve();
}

void vendorB::explain(IResolveDog& resolver)
{
    resolver.resolve();
}
Выбором интерфейса в main:

Код:
int main(int args, char** argv)
{
    my_namespace::Resolver resolver;
    vendor1::IResolveCat& catResolver = resolver;
    vendorB::IResolveDog& dogResolver = resolver;

    catResolver.resolve();
    dogResolver.resolve();

    return 0;
}
 

WMix

герр M:)ller
Партнер клуба
забыл что нибудь?
PHP:
<?php
interface IResolver{
  public function resolve();
}
interface IResolveDog{
  public function resolveDog();
}
interface IResolveCat{
  public function resolveCat();
}

class Dog implements IResolver{
   private $resolver;
  public function explain( IResolveDog $resolver ){
  $this->resolver = $resolver;
     $this->resolve();
  }
   public function resolve(){
     $this->resolver->resolveDog();
   }
   public function setResolver( IResolveDog $resolver ){
     $this->resolver = $resolver;
   }
}

class Cat implements IResolver{
   private $resolver;
  public function explain( IResolveCat $resolver ){
  $this->resolver = $resolver;
     $this->resolve();
  }
  public function resolve(){
     $this->resolver->resolveCat();
   }
   public function setResolver( IResolveCat $resolver ){
     $this->resolver = $resolver;
   }
}

class Resolver implements IResolveDog, IResolveCat{
  public function resolveCat(){
  echo "I'm a CAT resolved by Resolver";
  }
   
  public function resolveDog(){
  echo "I'm a DOG resolved by Resolver";
  }
}
$resolver = new Resolver;
$cat = new Cat;
$dog = new Dog;

//$cat->explain( new Resolver );
//$dog->explain( new Resolver );

$cat->setResolver( $resolver );
$dog->setResolver( $resolver );

$cat->resolve();
$dog->resolve();
 
Последнее редактирование:

fixxxer

К.О.
Партнер клуба
АХАХА, не дошли руки посмотреть релиз ... повеселило
Выгляит поначалу забавно, но вообще это разумно. Юзкейс трейтов зачастую как раз такой - дефолтные реализации _некоторых_ методов интерфейса, при этом этим реализациям нужны какие-то из остальных, нереализованых. Если в php трейту пофигу, что он дергает какбы undefined метод, то в джаве так не получится, и не вводя множественное наследование и монстроузных конструкций "trait for interface" - логичное и удобное решение.
 

fixxxer

К.О.
Партнер клуба
По котопсу, мне очень хочется предложить "решение" с debug_backtrace. Но я не буду.
 
  • Like
Реакции: AmdY

Lionishy

Новичок
fixxxer, подходящее решение уже найдено, в общем-то.

WMix, если есть какое-то иррациональное желание дальше доказывать, что пример C++ можно реализовать на PHP с конструкционной точки зрения, лучше уже в личные сообщения какие-нибудь. Вся тема превратилась в личную переписку.
 
Сверху