Пример PHP Duck — сначала в голову — шаблоны проектирования — глава первая

#php #design-patterns #interface

#php #шаблоны проектирования #интерфейс

Вопрос:

Это первый вопрос, который я задаю многим другим в будущем.

Кто-то здесь может назвать меня сумасшедшим, потому что я следую упомянутой книге в названии вопроса, используя PHP-OO.

В первой главе авторы представляют простой проект под названием «SimUDuck», и, хотя я воспроизвел то же самое на Java, мне было интересно воспроизвести то же самое с помощью PHP.

В конце проект SimUDuck создает два (2) интерфейса (FlyBehavior и QuackBehavior), более пяти (5) классов, реализующих эти интерфейсы (например, FlyWithWings(), Quack() и т.д.), абстрактный класс с именем Duck и три (3) или четыре (4) класса разных видов уток, расширяющих Duck (Mallard, HeadRedDuck, RubberDuck и т.д.), Просто чтобы продемонстрировать, насколько важно программировать для интерфейса.

Для имитации среды Java main method я создал класс PHP под названием MiniDuckSimulator, включающий функцию ‘public static function main()’ и в тот же скрипт я добавил «MiniDuckSimulator::main();». Скрипт работает без ошибок.

Интригующая проблема заключается в том, что без вызова какого-либо метода, реализованного QuackBehavior::quack(), echo ‘Quack!появляется quack!’. Те, кто читал эту книгу, знают, о чем я говорю.

Примечание: Ниже приведена определенная часть скрипта:


 interface FlyBehavior {
    public function fly();
}
  

 interface QuackBehavior {
    public function quack();
}
  

 include_once 'FlyBehavior.php';

class FlyWithWings implements FlyBehavior {

    public function fly() {
        echo 'I'm flying!<br />';
    }

}
  

 include_once 'QuackBehavior.php';

class Quack implements QuackBehavior {

    public function quack() {
        echo 'Quack!<br />';
    }
}
  

 abstract class Duck {

    protected $flyBehavior;
    protected $quackBehavior;

    function  __construct() {
    }

    public function performFly(){
        $this->flyBehavior->fly();

    }

    public function performQuack(){
        $this->quackBehavior->quack();

    }

    public function setFlyBehavior($flyBehavior){
        $this->flyBehavior = $flyBehavior;
    }

    public function swim(){
        echo "All the ducks float, including the decoy!<br />";
    }
}
  

 include_once 'Duck.php';
include_once 'FlyWithWings.php';
include_once 'Quack.php';

class Mallard extends Duck {

    function __construct() {
        $this->flyBehavior = new FlyWithWings();
        $this->quackBehavior = new Quack();
    }

}
  

 class MiniDuckSimulator {
    public static function main(){
        $mallard = new Mallard();
        $mallard->performFly();
    }

}

MiniDuckSimulator::main();
  

Заранее спасибо.

Удачно.

Комментарии:

1. У меня болят глаза при чтении текста:-S

2. Извините за это. Я бы сделал это коротким, но пропустил бы некоторую важную информацию для тех, кто заинтересован помочь мне.

3. Двойное «кряканье» совершенно бесполезно. Это может быть один и тот же метод, вызванный дважды, или метод и родительский класс. Я бы добавил немного текста вроде «quack-rubber» и «quack mallard» и т.д.

4. Это лучше???? Теперь о «фрагментах кода», это было бы невозможно, потому что это примерно 10 разных файлов. Что бы я сделал, так это прикрепил эти файлы куда-нибудь.

5. Один из наших коллег беллоу (ник Мачек) ответил на вопрос. Проблема заключалась в том, что класс Quack имел метод quack(), и, поскольку PHP будет обрабатывать любой метод с тем же именем, что и класс, как конструктор класса, когда я вызываю «$mallard = new Quack()», содержимое метода quack() будет выполнено. То, что я сделал, было простым… измените имя класса на NormalClass, вот и все.

Ответ №1:

Причина, по которой вы видите Quack!<br /> вывод, заключается в следующем:

 class Quack implements QuackBehavior {

    public function quack() {
        echo 'Quack!<br />';
    }
}
  

Вот ваша проблема: если вы просто запустите new Quack(); quack() метод, он автоматически выполняется php как конструктор, потому что у него то же имя, что и у вашего класса. — Я вижу, вы ссылались на Java в своем вопросе, так что это не должно быть для вас чуждой концепцией.

 new Quack(); // => Quack!<br />
  

Потенциально лучший способ

 <?php

interface CanFly {
  public function fly();
}

interface CanQuack {
  public function quack();
}

abstract class Duck implements CanFly, CanQuack {

  protected $color = "DEFAULT"

  public function fly(){
    echo "I'm flying with my {$this->color} wingsn";
  }

  public function quack(){
    echo "I'm quackingn";
  }

  public function swim(){
    echo "I'm swimmingn";
  }
}

class Mallard extends Duck {

  public function __construct(){
    $this->color = "green";
  }

  public function quack(){
    echo "My quack sounds more like a honkn";
  }
}

$m = new Mallard();
$m->fly();
$m->quack();
$m->swim();

?>
  

Вывод

 I'm flying with my green wings
My quack sounds more like a honk
I'm swimming
  

Комментарии:

1. Что касается ошибки echo, я уже объяснил, почему. Это потому, что я бразилец, а на португальском мы говорим «Estou voando!», не используя одинарную кавычку внутри строки, и после вставки я перевел строку на английский. Не беспокойтесь о втором «кряканье!». Я отредактировал содержимое строки, чтобы воспроизвести только одно «кряканье» (для меня это уже слишком кряканье !!!! :). Что касается фактического кода, который вы упомянули, код, который я вставил, является фактическим кодом.

2. Я не смогу вам помочь, если вы не собираетесь читать ответ. Причина, по которой вы видите a, Quack!<br /> заключается в том, что у вас есть функция quack() с тем же именем, что и у Quack класса, и php автоматически обрабатывает ее как конструктор. Я добавил еще несколько правок, которые могут помочь вам увидеть, как сделать это потенциально лучшим способом…

3. Извините… Теперь я понял, что не увидел ответа, который вы дали после горизонтальной линии, и вы абсолютно правы. Большое вам спасибо. Я забыл, что PHP будет обрабатывать любой метод с тем же именем, что и класс, как конструктор класса. Что я сделал, так это переименовал класс Quack в NormalQuack, и весь скрипт работал хорошо. Еще раз большое вам спасибо.

4. Я думаю, что это не лучший способ, потому что он говорит о книге Head First — Шаблоны проектирования, в книге этот пример о том, как не реализовывать quack и летать внутри класса duck, потому что, например, резиновая утка не может летать. Они предлагают создавать интерфейсы и классы и для этого выполнять действия, а затем использовать объекты в конструкторе класса Duck.

Ответ №2:

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

Повторно проанализируйте свой код и поищите хитрый способ, которым ваше echo «Крякнет!выполняется quack!’.

Комментарии:

1. Прежде всего, спасибо за быстрый ответ. Хотя этого может быть недостаточно, но ниже приведено содержимое «функции main()»: $mallard = new Mallard(); $mallard->performFly(); // больше ничего.

2. Во-первых, приведенные выше комментарии просят вас разбить ваш вопрос, а не уменьшать его. Это слишком сложно для чтения. Во-вторых, утки, как известно, крякают, когда рождаются или летают. Я шучу. Но если серьезно, должно быть что-то, вызывающее ваш метод, который содержит инструкцию ‘echo’. он не будет вызывать сам себя. Кое-что должно быть упущено из виду.

3. Я надеюсь, что теперь вопрос стал лучше читаться. Если вы прочитали книгу и протестировали тот же образец, используя Java (я полагаю, вы это сделали), единственное, что вам нужно сделать, это заменить пространство имен Java (например, «System.out.println», void) и объявление на PHP, не более. (Конечно, если у вас есть для этого свободное время).

4. Я не читал книгу. Моим ответом было предложение подойти к вашей проблеме с критическим мышлением. Столкнитесь с проблемой -> предположите ошибку с вашей стороны -> найдите и исправьте ошибку. Я хотел бы помочь вам больше.

5. «Возникла проблема ->» Я пытался!!! «допустим ошибку с вашей стороны ->» Я предполагаю, что со вчерашнего дня я не нашел решения, и это одна из причин, почему я задал этот вопрос. «найдите и исправьте ошибку» если я не исчерпал все возможности, которые пришли мне в голову, опять же, я не задавал этот вопрос и вызвал так много сомнений в умах участников.

Ответ №3:

Прокомментируйте эту строку:

 echo 'Quack!<br />';
  

Вы видите еще какие-нибудь шарлатанства? Если это так, то в вашем коде есть echo / exit / die с этой строкой!

Комментарии:

1. Это всего лишь один шарлатан, ребята!!! Я отредактировал результат echo, чтобы воспроизвести только один. Это потому, что в примере книги авторы, поскольку им очень нравятся утки, написали ‘System.out.println’ с двумя (2) «кряками!». Не имеет значения.

Ответ №4:

Это потому, что когда у вас есть класс с тем же именем метода, PHP рассматривает его как конструктор. Это уже устарело в php 7 и скоро будет прекращено. Вы можете увидеть это в онлайн-документации: http://php.net/manual/en/migration70.deprecated.php